fbpx
Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1

TOPIC: 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 09 May 2020 12:53 #14499

  • mainhatten's Avatar

  • mainhatten

  • Topic Author


  • Posts: 139
  • Hi,

    trying to get a clear picture on the different NULLs in xSharp.
    On Bandol 2.2 there is a list of "Null Literals", which at least is missing an entry for NULL_DATETIME and perhaps for NULL_CURRENCY - second OTOH might be handled via nullable 8-bit int behind currency.

    Topic of NIL is sometimes mentioned, but has no own entry beyond "NILs, assigning default values" which makes no sense to me, as it is unclear if "Assign a default value to a NIL argument" is meant for Core or VO dialect, as vfp casts missing parameters to false booleans.

    Dotnet has (besides none member in various classes) its own speciality: the DBNull different from Null used on vars, see for instance
    www.c-sharpcorner.com/blogs/handling-dbnull-in-c-sharp1
    and DBNull is not mentioned in xSharp docs on 2.2

    Vfp memory uses "handles" as possible data type, but these handles either point to an object or other data type (including option to assign NULL value / NULL value assigned if Form is released), OTOH nullable vfp data columns can be updated/replaced with such NULL values - at the moment I see nothing mirroring the null / DBNull split of Dotnet.

    Can you shed some light on how this works in xSharp ? Is "memory null" automatically transferred into DBNull and vice versa ?
    Found in xSharpRDD.../DbfFPt.Prg
                    CASE FlexArrayTypes.NIL
                        element := DBNull.Value
    Found in xSharpCore.../Error.Prg in STATIC METHOD TypeToUsualType(oType AS System.Type) AS DWORD
        CASE TypeCode.DBNull
          RETURN __UsualType.Object

    Found in xSharp.RT/.../Usual_Reftypes.Prg
                        var typeCode := System.Type.GetTypeCode(vartype)
                        switch typeCode
                            case  System.TypeCode.DBNull
                                self:_flags:usualType := UsualType.Void
                                self:_refData	:= null

    Also found in VOSDK/.../SQL_Functions.Prg an assign to NIL and more mentions in other Select?.Prg there as part of member names.

    Cannot say I have a clear mental picture ;-)

    Why ask now ? Because Robert hinted at public 2.4a release soon. All those NULL errors in String and possibly other RT functions should be doable after hammering out a schema with dev team on how and where (Vfp only? Or inside Core level?) to fix by coders outside dev team and work can be done on a current release without worry of missing something already changed in in-between FOX-only versions.

    Might be better if such issues can be summed up as in "known, worked on already" as a single issue entry if new vfp coders can be enticed to test as more vfp functionality is implemented - adding a few dozen entries basically amounting to NULL-handling differences would only fog the issue and inflate issue count beyond reasonable, creating a wrong opinion on the hurdles to take till usable. Vfp IsNull() and NVL() functions could probably handled en passant.

    my 0.22€ (might take a few cents worth of fixing if nobody steps up)
    Thomas

    Please Log in or Create an account to join the conversation.

    Last edit: by mainhatten.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 09 May 2020 13:17 #14500

  • robert's Avatar

  • robert


  • Posts: 1676
  • Thomas,
    The concept of .NULL. like VFP has is new to people coming from VO.
    On the other hand, the concept of NIL, which is common to VO people (as well as XBase++ people) is new to VFP developers.
    And unfortunately they are different.
    For VO developers it is clear that NIL is the value of uninitialized untyped variables (usuals).
    Technically this means the usual structure is filled with all zeros.
    On the other hand, for us, coming from the VO world, it was very weird to see that in VFP uninitialized variables have a value of FALSE.
    We remembered that this was the case in DBase with PRIVATE and PUBLIC memory variables, but certainly not with local variables
    or fields and properties.

    And of course in the .Net world we now also have the concept of DbNull.Value , which seems to map the NULL value from the database world.

    I think we need to come with a plan how to implement all of these in a away that works for everybody.

    I have already tried to merge the concept of the VO compatible NIL and "Foxpro unitialized FALSE' in the USUAL type: when the dialect is FoxPro then the default NIL is a FALSE with a "initialized flag" set to FALSE and the type flag set to LOGIC. For other dialects (except Core, there is no USUAL in core) NIL is represented as the absense of a value, the "initialized flag" is also FALSE and the type is set to VOID (0).
    The internal IsNil property of the usual type and the IsNil() runtime function now takes care of handling the different situations. So it returns TRUE when the type flag is VOID, when the Initialized flag is FALSE and also (this is a VO inconsistency) when the type is a reference type and value is NULL or when the type is PTR and the value is IntPtr.Zero.
    See github.com/X-Sharp/XSharpPublic/blob/mas...Types/Usual.prg#L455

    I think we somehow also need to add support for DbNull.Value in there (maybe as an additional __UsualType)

    W.r.t. NULL_DATE. This is supported by the compiler but maybe not included in the help. I'll look into that
    I personally see no need for NULL_CURRENCY, NULL_LONG or NULL_FLOAT. These can be either 0 or DbNull.Value.




    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 09 May 2020 13:19 #14501

  • wriedmann's Avatar

  • wriedmann


  • Posts: 2232
  • Hi Thomas,
    from what I know:
    • NIL is an own datatype, and AFAIK ist can be assigned only to variables defined as usual. In the function and methods woth the Clipper calling convention not passed variables are seen as NIL
    • NULL is specific to the .NET Framework (in VO we don't have it) and means AFAIK that the variable was not inizialized
    • DBNull AFAIK is returned only by SQL calls
    In VO, we have a null datatype for some datatypes (and VFP has the same, I think): NULL_STRING, NULL_DATE. Numerics and logic don't have a null value, they are either 0 (numeric) or false (logic).
    Strings have a different behavior in .NET and in VO: a not initialized string on .NET is NULL, whereas in VO it is a NULL_STRING (not the same as ""). A NULL_STRING can be used in string comparisions, a NULL string value not. Therefore X# has a compiler switch to initialize all string variables.
    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 09 May 2020 16:57 #14503

  • mainhatten's Avatar

  • mainhatten

  • Topic Author


  • Posts: 139
  • Hi Robert,
    now just 2 items in your post raising flag here:

    robert wrote: On the other hand, for us, coming from the VO world, it was very weird to see that in VFP uninitialized variables have a value of FALSE.
    We remembered that this was the case in DBase with PRIVATE and PUBLIC memory variables, but certainly not with local variables
    or fields and properties.

    Nope, only PUBLIC global var is created at top level by the PUBLIC statement as boolean false. From vfp help:
    PRIVATE doesn't create variables; it simply hides variables declared in higher-level programs from the current program.
    Although I cannot think of any normal vfp program depending on having "uninitialzed" private as a feature. But running xSharp code under vfp might run into problems if private created and initialized variables.

    W.r.t. NULL_DATE. This is supported by the compiler but maybe not included in the help. I'll look into that
    I personally see no need for NULL_CURRENCY, NULL_LONG or NULL_FLOAT. These can be either 0 or DbNull.Value.

    NULL_DATE is mentioned in help: NULL_DATETIME is not, unless NULL_DATE works for datetime variables as well - then the naming is not really self-explaining.

    More later...

    thomas

    Please Log in or Create an account to join the conversation.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 09 May 2020 18:10 #14504

  • robert's Avatar

  • robert


  • Posts: 1676
  • Thomas,

    Maybe Private does not create any variables, but LOCAL does. And were surprised to see that also LOCAL variables in FoxPro are initialized with FALSE. And based on all the behavior we see (locals being visible to functions like Type(), Evaluate() and (when embedded in a sql statement) SqlExec() and SqlPrepare() , they are not even true locals. They are also visible (at least to the VFP runtime) outside of the scope where they are defined.
    And w.r.t. NULL_DATETIME: the datetime type does not support something like that. The closes to that are either Nullable<DateTime> or DateTime.MinValue.
    The Date type however does have a NULL_DATE value, where year, month and day are all 0.

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    Last edit: by robert.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 09 May 2020 20:48 #14505

  • atlopes's Avatar

  • atlopes


  • Posts: 38
  • I am trying to contribute to the info gathering, related only to VFP .NULL., while keeping it as neutral as possible.

    Yes, all PUBLIC or LOCAL unassigned variables are initialized to .F., and the same happens to function arguments: that is, a declared parameter that is not passed to a function has the value of .F.

    A variable or a property has always a type, even if it has been nullified. By default, it's Logical. Otherwise, it's of the type of the last non-null assignment (including the Object type, and therefore even if the object is gone).

    Expressions can be of type .NULL., if they evaluate to .NULL.

    From the two rules above:
    LOCAL x
    
    y = .NULL.
    ? TYPE("y")  && prints L
    ? VARTYPE(y)  && prints X
    
    ? TYPE("x")  && prints L
    ? VARTYPE(x)  && prints L

    Date, Datetime, and Blob variables and fields can be assigned as empty, but also can also become .NULL. If they are empty, they are not .NULL., if they are .NULL., they are not empty.

    Empty literals for Date, Datetime, and Blob
    ? VARTYPE({})   && prints D
    ? VARTYPE({/:})   && prints T
    ? VARTYPE(0h)   && prints Q

    As I mentioned in another thread, when .NULL. is allowed as an argument to a function, and with some obvious exceptions like testing for .NULL., the function normally returns .NULL. (Thomas pointed out that is not the case with some string functions, but I confess I'm failing to locate which ones).

    Please Log in or Create an account to join the conversation.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 09 May 2020 23:22 #14506

  • mainhatten's Avatar

  • mainhatten

  • Topic Author


  • Posts: 139
  • Hi Antonio

    atlopes wrote: I am trying to contribute to the info gathering, related only to VFP .NULL., while keeping it as neutral as possible.

    Was not aware that the thread might be interpreted as "having sides" - if I wrote something to evoke that, was not intended.

    Yes, all PUBLIC or LOCAL unassigned variables are initialized to .F., and the same happens to function arguments: that is, a declared parameter that is not passed to a function has the value of .F.
    .......

    ? VARTYPE({/:})   && prints T
    ? VARTYPE(0h)   && prints Q

    All true - but there is also IsBlank(), Append blank, Blank: those were used in 2.x times sometimes as a poor mans .Null. on Floats, Decimal, Boolean, making code brittle IMO and I hated such practice:
    Perhaps this is nearest thing to the "uninitialized" concept of NIL in VO and xBase which Robert described. I only knew NIL from Pascal and Modula2 as Zeropointer or "Not in List" of a Pointer variable whose pointed to structure had been not initialised or released - therefore my hint to form.Release().
    As Integer, Double and Currency don't support the "blank" concept I prefer them a lot in vfp...

    As I mentioned in another thread, when .NULL. is allowed as an argument to a function, and with some obvious exceptions like testing for .NULL., the function normally returns .NULL. (Thomas pointed out that is not the case with some string functions, but I confess I'm failing to locate which ones).

    I picked the ones to implement in 2.3 not only because I used them a lot, but also because I did not have to code for IsNull() changing the return values..
    ? GETWORDCOUNT("Hallo vfp Null" + CHR(10) + "check")
    ? GETWORDCOUNT("Hallo vfp Null" + CHR(10) + "check", .null.)
    ? GETWORDCOUNT(.null.)
    ? GETWORDNum("Hallo vfp Null" + CHR(10) + "check",3)
    ? GETWORDNum("Hallo vfp Null" + CHR(10) + "check",.null.)
    ? ADDBS(.null.)
    ? FORCEEXT(.null., "txt")
    and so on - comes probably from FoxTools heritage ;-)
    Wanted to some other things like StrExtract(), but there you have the .Null. check needed - which could probably be done for strings in Core with "is Null" or String.IsNullOrEmpty() but instead of tying in such concepts for Usuals as well I decided to skip

    regards
    thomas

    Please Log in or Create an account to join the conversation.

    Last edit: by mainhatten.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 10 May 2020 00:12 #14507

  • atlopes's Avatar

  • atlopes


  • Posts: 38
  • Thomas

    Was not aware that the thread might be interpreted as "having sides" - if I wrote something to evoke that, was not intended.


    No, no, I was not and I am not thinking you wrote anything of the kind. I was just stressing that my contribution will not convey any judgment whatsoever regarding how VFP deals with Nulls, be it positive or negative. I'm just trying to pass info that I am aware of, as straightforward as I can.

    Regarding the examples you gave, I still maintain what I said previously: when .NULL. is allowed as an argument of a VFP function, the function returns .NULL. The cases you presented do not allow .NULL. as parameters, and they raise an error, instead.

    The nullification also affects expressions in which .NULL. values are used as operands. More examples:
    ? SQRT(.NULL.)   && prints .NULL.
    ? DATETIME() + .NULL.   && prints .NULL.
    ? 25 / .NULL.   && prints .NULL.

    Exceptions that I know of: logical AND operations in which one of the operands is .F., or logical OR operations in which one of the operands is .T.

    Please Log in or Create an account to join the conversation.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 10 May 2020 08:12 #14509

  • mainhatten's Avatar

  • mainhatten

  • Topic Author


  • Posts: 139
  • Antonio

    atlopes wrote: Regarding the examples you gave, I still maintain what I said previously: when .NULL. is allowed as an argument of a VFP function, the function returns .NULL. The cases you presented do not allow .NULL. as parameters, and they raise an error, instead.

    In my diction anything not forbidden/constrained in the docs (for example describing allowed parameter types or count) is allowed. For instance often possible data types are described.
    The return of .null. from strextract() when called with a .null. parameter makes as much sense to me as returning .null. from addBS() would - not a really usable return value, so IMO throwing an error there could be exchanged for returning .null. without much difference to calling program when looked at it from eagle eye position - would need other error checking/wrapping, but result still unusable. Or - put in your "Nullification" context - when
    lxNull .= Null + "\"
    ? lxNull
    resolves to null, why stop AddBS() from doing the same, as docs does not mention .null. values there or at StrExtract? I classify error thrown in AddBS() as implementation detail same as returning .null. is in StrExtract().

    I had wondered a bit on your choice of words with "allowed", as Vfp does not support the distinction of nullable and not nullable types which were part of Kotlins lure over Java as integral part of the language and which Dotnet introduced early on as well, while much of Java depends on annotations (IMO too much, Lombok already at the border of "too much magic").

    Interpreted it as encompassing statement including languages like Kotlin/C#, whereas you intended to mark "throwing errors" as "not allowed". I still think "errorthrowing" in those functions comes from directly compiling C++ code written for FPD/FPW, where there was no concept of .null. inside the language and the handling of functions like StrExtract() more in line of functions usable from SQL, where an error thrown on 1 particular record with a .null. value in worked on column is worse than returning .null. for that particular row. Result is still "I don't know", but processing can continue if table allowed nullable column value. Might not be that clear in AddBS() case, but JustExt() can be used on columns as well as "pattern analysis", but carries that threat making direct SQL usage brittle.

    my 0.02€
    thomas

    Please Log in or Create an account to join the conversation.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 10 May 2020 13:02 #14511

  • atlopes's Avatar

  • atlopes


  • Posts: 38
  • Thomas,

    I don't want to be too picky on this matter. As I said, I aim to help gather as much information as possible to the X# team so that they can make their decisions on the VFP implementation.

    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,
    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.

    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.

    Please Log in or Create an account to join the conversation.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 10 May 2020 15:58 #14512

  • robert's Avatar

  • robert


  • Posts: 1676
  • 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
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 10 May 2020 16:45 #14514

  • atlopes's Avatar

  • atlopes


  • Posts: 38
  • 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).
    LOCAL tn AS n
    
    m.tn = CREATEOBJECT("n")
    
    ? "("
    
    m.tn = .NULL.
    
    ? ")"
    
    DEFINE CLASS n AS Custom
    
    	PROCEDURE Destroy
    
    		? "Being released..."
    
    	ENDPROC
    
    ENDDEFINE

    prints
    (
    Being released...
    )

    I don't know how this adjusts to your plans.

    Now, </neutral>

    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 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 statements
    SELECT COUNT(*) FROM someTable WHERE someNilableColumn = NULL;
    SELECT COUNT(*) FROM someTable WHERE someNilableColumn IS NULL;

    are not equivalent and the first will always return 0, no matter what.

    Please Log in or Create an account to join the conversation.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 10 May 2020 17:33 #14515

  • mainhatten's Avatar

  • mainhatten

  • Topic Author


  • Posts: 139
  • Hi Robert,

    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.

    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.

    - 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.


    Here I am uncertain,
    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);
    }
    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

    Please Log in or Create an account to join the conversation.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 10 May 2020 17:40 #14516

  • robert's Avatar

  • robert


  • Posts: 1676
  • 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
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 10 May 2020 17:44 #14517

  • mainhatten's Avatar

  • mainhatten

  • Topic Author


  • Posts: 139
  • Hi Antonio,

    atlopes 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,

    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.

    What I meant was that the Foxtools originating functions are less adapted to SQL. Enhancing your example a bit
    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
    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.

    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.


    Agreed. If they ban IsBlank or Blank I would not protest much as long as null is fully supported.

    regards
    thomas

    Please Log in or Create an account to join the conversation.

    Last edit: by mainhatten.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 10 May 2020 17:46 #14518

  • mainhatten's Avatar

  • mainhatten

  • Topic Author


  • Posts: 139
  • robert wrote: So "null" for strings is allowed of course.


    Good.

    regards
    Thomas

    Please Log in or Create an account to join the conversation.

    More info needed for xSharp on different Null(s), Nil, DotNet DBNull, None 10 May 2020 23:32 #14519

  • mainhatten's Avatar

  • mainhatten

  • Topic Author


  • Posts: 139
  • Robert, one slight correction (had to verify some nagging vague memory first)

    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.

    The reason being SQL already discussed, but I guess you checked with iif(null==null)
    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:
    ln1 = null
    ln2 = null
    lnErg = (ln1=ln2)
    ? lnErg
    lnErg = (ln1==ln2)
    ? lnErg
    ? IIF(lnErg, "= true", "= false")

    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

    Please Log in or Create an account to join the conversation.

    Last edit: by mainhatten.
    • Page:
    • 1