Thomas, Antonio,
At this moment we plan the following (and this will not be included in the coming build by the way):
- we're not going to invent new type
- The literal .NULL. will be compiled to DbNull.Value. That is a DotNet standard for NULL database values.
- When .NULL. or DbNull.value is stored in a Usual we will assign it a new UsualType. We'll make its ValType and VarType "X" and its "ToString()" will be ".NULL."
- The IsNull() function will return TRUE for USUAL values with this type.
- The various operators in the Usual class will allow adding / subtracting USUAL values with .NULL. and will return .NULL., just like VFP does
- I did a check with VFP and if you assign .NULL. to a variable (let's say A) then the comparison A == .NULL. returns FALSE even when A has the value .NULL. That does not really make sense, but we'll implement that too. We'll also implement all the other operators on the USUAL type to work just like VFP, so when usual A has .NULL. and usual B has "A" the result of A + B will be .NULL..
- In VFP the expression (considering again that A has the value .NULL.) "IF A" will also not evaluate to TRUE so will go into the ELSE branch of the IF statement. We'll implement that too.
- And As long as you don't strongly type your code this should all be fine. When you start strong typing your code then assigning a value of .NULL. to a type variable, such as for example a STRING will generate an error. Assigning a literal .NULL. to a STRING will generate a compiler error (since the compiler knows that you cannot assign DBNull.value to a string).
If you assign an untyped variable containing .NULL. to a string will generate a runtime error, since there is no real conversion.
Robert
More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None
More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None
Robert,
Ok. we'll see how this will work against actual code.
Just one more bit of information: assign a NULL to an object variable is common practice in VFP code to release the object (starting with the official documentation).
prints
I don't know how this adjusts to your plans.
Now, </neutral>
are not equivalent and the first will always return 0, no matter what.
Ok. we'll see how this will work against actual code.
Just one more bit of information: assign a NULL to an object variable is common practice in VFP code to release the object (starting with the official documentation).
Code: Select all
LOCAL tn AS n
m.tn = CREATEOBJECT("n")
? "("
m.tn = .NULL.
? ")"
DEFINE CLASS n AS Custom
PROCEDURE Destroy
? "Being released..."
ENDPROC
ENDDEFINE
Code: Select all
(
Being released...
)
Now, </neutral>
In fact, it makes a lot of sense and encapsulates perfectly well the place and purpose of NULL in VFP. NULL is not a value, it can't be compared to anything, including itself. And VFP is far from being alone in this approach. In standard SQL, these two statementsI did a check with VFP and if you assign .NULL. to a variable (let's say A) then the comparison A == .NULL. returns FALSE even when A has the value .NULL. That does not really make sense, but we'll implement that too.
Code: Select all
SELECT COUNT(*) FROM someTable WHERE someNilableColumn = NULL;
SELECT COUNT(*) FROM someTable WHERE someNilableColumn IS NULL;
-
- Posts: 200
- Joined: Wed Oct 09, 2019 6:51 pm
More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None
Hi Robert,
is valid C# of MS documentation. Does your text mean that in xSharp strings cannot be "null" any more or just that they cannot be assigned the DBNull.value used in RT? Problem here is probably that .Null. and null are synonymous in vfp code - I must think a bit on that.
Current way of thinking is that Core/stong typed xSharp should support the concept of "null" in POCOs by having nullable strings and other variables, so IMO the distinction C# makes between "null" and DBNull should be mirrored in xSharp. But that is first impression, not really thought through.
my 0.02€
thomas
Antonio beat me pointing to SQL as reason for .Null. # .Null. making sense - my example would have been an inner join, where including on "I don't know" probably is not wished for. Reads ok, including DBNull.Value as default for nulled Usuals.robert wrote: ...
- I did a check with VFP and if you assign .NULL. to a variable (let's say A) then the comparison A == .NULL. returns FALSE even when A has the value .NULL. That does not really make sense, but we'll implement that too. We'll also implement all the other operators on the USUAL type to work just like VFP, so when usual A has .NULL. and usual B has "A" the result of A + B will be .NULL..
- In VFP the expression (considering again that A has the value .NULL.) "IF A" will also not evaluate to TRUE so will go into the ELSE branch of the IF statement. We'll implement that too.
Here I am uncertain,- And As long as you don't strongly type your code this should all be fine. When you start strong typing your code then assigning a value of .NULL. to a type variable, such as for example a STRING will generate an error. Assigning a literal .NULL. to a STRING will generate a compiler error (since the compiler knows that you cannot assign DBNull.value to a string).
If you assign an untyped variable containing .NULL. to a string will generate a runtime error, since there is no real conversion.
Code: Select all
string s1 = "abcd";
string s2 = "";
string s3 = null;
Console.WriteLine("String s1 {0}.", Test(s1));
Console.WriteLine("String s2 {0}.", Test(s2));
Console.WriteLine("String s3 {0}.", Test(s3));
String Test(string s)
{
if (String.IsNullOrEmpty(s))
return "is null or empty";
else
return String.Format("("{0}") is neither null nor empty", s);
}
Current way of thinking is that Core/stong typed xSharp should support the concept of "null" in POCOs by having nullable strings and other variables, so IMO the distinction C# makes between "null" and DBNull should be mirrored in xSharp. But that is first impression, not really thought through.
my 0.02€
thomas
More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None
Thomas,
From the Ms Docs on DbNull:
Do not confuse the notion of null in an object-oriented programming language with a DBNull object. In an object-oriented programming language, null means the absence of a reference to an object. DBNull represents an uninitialized variant or nonexistent database column.
So "null" for strings is allowed of course.
Robert
From the Ms Docs on DbNull:
Do not confuse the notion of null in an object-oriented programming language with a DBNull object. In an object-oriented programming language, null means the absence of a reference to an object. DBNull represents an uninitialized variant or nonexistent database column.
So "null" for strings is allowed of course.
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
-
- Posts: 200
- Joined: Wed Oct 09, 2019 6:51 pm
More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None
Hi Antonio,
might not be totally construed examples. StrExtract() is easy to use over the table, if I want to find longest file name length I have to guard the function - here done with iif(), in real code probably with a wrapper function returning .Null. on IsNull(). Takes longer to write about it then to code, so let us drop the theme.
regards
thomas
What I meant was that the Foxtools originating functions are less adapted to SQL. Enhancing your example a bitatlopes wrote:That said, and starting to get a bit judgmental here, I don't think that VFP's NULL approach is consistent all the way in every corner, I'm fully agreeing with you. It won't be too hard to find some Wat moments.
Furthermore, in their specific area, VFP SQL commands (the great mountain ahead for the X# team to climb) follow the ANSI rules. For instance,
Code: Select all
CREATE CURSOR x (n Int NULL) INSERT INTO x VALUES (1) INSERT INTO x VALUES (.NULL.) SELECT MAX(n) FROM x && shows 1
The only reasonable scenario I anticipate where we would throw a NULL inside a built-in VFP function is when the value comes from an external source, like a query, or a result from a method call, or the value of a property. But this is me not being neutral anymore.
Code: Select all
CREATE CURSOR x (n Int NULL, se CHR(20) Null, js CHR(20) Null)
INSERT INTO x VALUES (1, "< for extract >", "c:fil.txt")
INSERT INTO x VALUES (5, "< for ext >", "c:filname.txt")
INSERT INTO x VALUES (.NULL., .null., .null.)
SELECT MAX(n) ;
, MAX(LEN(STREXTRACT(Se, "<", ">"))) ;
, MAX(LEN(IIF(ISNULL(Js), .Null., JUSTSTEM(js)))) ;
FROM x
Agreed. If they ban IsBlank or Blank I would not protest much as long as null is fully supported.Nevertheless, I think that being able to distinguish between NULL and any other value, including empty values, should be a fairly expectable target for a VFP implementation, and I hope X# succeeds in this.
regards
thomas
-
- Posts: 200
- Joined: Wed Oct 09, 2019 6:51 pm
More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None
Good.robert wrote: So "null" for strings is allowed of course.
regards
Thomas
-
- Posts: 200
- Joined: Wed Oct 09, 2019 6:51 pm
More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None
Robert, one slight correction (had to verify some nagging vague memory first)
In effect if deciding outcome/program flow on boolean criterion the above is stlll true, but the underlying mechanism is slightly different, the comparison returns .null., which then works as .f. if checked as Boolean:
BTW: Having read up on Dotnet Nullable value and reference types I can understand you staying first with Usual and own nullable implementation - head is reeling, and if I understood Dotnet "thinks" your way in checking nullable value types for equality - I still think SQL is more important for a DB language, but perhaps creating NullSqlEqual and NullVarEqual extension methods might make sense if you want to enable nullable types in Core at some later time. Holler if you want Short code examples of vfp SQL joins with nulls
regards
thomas
The reason being SQL already discussed, but I guess you checked with iif(null==null)robert wrote: - I did a check with VFP and if you assign .NULL. to a variable (let's say A) then the comparison A == .NULL. returns FALSE even when A has the value .NULL. That does not really make sense, but we'll implement that too.
In effect if deciding outcome/program flow on boolean criterion the above is stlll true, but the underlying mechanism is slightly different, the comparison returns .null., which then works as .f. if checked as Boolean:
Code: Select all
ln1 = null
ln2 = null
lnErg = (ln1=ln2)
? lnErg
lnErg = (ln1==ln2)
? lnErg
? IIF(lnErg, "= true", "= false")
regards
thomas