Compilation error or behavior opposite to that of FoxPro in call to function Empty()
Good morning guys I repeat this requirement here at the request of Robert but I clarify that it is the same error reported in the Xsharp forum for beta testers
Compilation error or behavior opposite to that of FoxPro in call to function Empty() when the argument value is null. Less imprortant, the compiler error commented in source code. Next a FoxPro Dialect Console Application
USING System USING System.Collections.Generic USING System.Linq USING System.Text USING System.Data USING XSharp.Data USING XSharp.RDD
FUNCTION Start() AS VOID STRICT ? "Hello World! Today is ",Date() ? Empty(.f.) // return true correctly ? Empty(.t.) // return false correctly local lnull:= null ? Empty(lnull) // return true and in FoxPro return false ? Empty(.null.) // return true and in FoxPro return false
// next line produce compiler error and in FoxPro it is valid and return false // ? Empty(null) //Severity Code Description Project File Line Suppression State //Error XS0121 The call is ambiguous between the following methods or properties: 'XSharp.RT.Functions.Empty(array)' and 'XSharp.RT.Functions.Empty(symbol)'
Juan,
Your example mixes the use of NULL and .NULL.
I checked and Foxpro indeed allows to use NULL as alternative for .NULL. but this not documented.
The only place where the FoxPro docs speak about NULL without the dots is inside SQL statements, not as a valid FoxPro value.
We have already adjusted the runtime to return FALSE for Empty(.NULL.) (See 4107a9d6e65eea24b98d1f9bb10c6e6200a91195)
It will be VERY difficult to do the same for NULL, or we would have to code an exception for the FoxPro dialect.
However since NULL is not documented as acceptable value for FoxPro I think this is a bad idea.
You can see in VFP help on line the captions NULL as a Value or NULL as a Parameter or Null Value Handling NULL is a constant, a clause and any variable can value NULL. Perhaps the online help does not formalize it clearly but it means exactly the same thing although we cannot prove it since it is an incomparable value. Perhaps the following example will show that .NULL. and NULL are exactly the same since the output values is .NULL.
CLEAR MEMORY
STORE 5 TO nX
nX = NULL
? TYPE ("nX") // I put the example to clalarify that particularity
? nx // the ouput is .NULL.
nY = .NULL.
? nY // the ouput is .NULL. too
Juan, We will try to implement this in the next build. I am not sure yet how we will do that. I see 2 options:
- The compiler could treat
NULLdifferently in the FoxPro dialect and output DBNull.Value just like it does for.NULL.. That would mean that it no longer can be used for an empty reference type (howeverNULL_ARRAY,NULL_OBJECT,NULL_STRING,NULL_PTRwould still work) - No changes to the compiler, but treat NULL differently in the USUAL type for the FoxPro dialect. The USUAL type is the parameter type for functions such as
Empty()andQOut()(The function that is called by the?command
At this moment I have a small preference for the second option.
Null is similar to zero pointer in C++. So it is a reference which not pointing to any value. In c# means the variable reference declared of type T "no has value" , similar to C++
DBNull.Value is completely different and is a constant which is returned when a field value contains NULL. Then NULL* declarations are the confusion and i am sure they came with a long history that only you know.
USUAL is a struct and the property IsNull is a bit estrange in XSHARP help: "This property returns TRUE when the USUAL is of type BINARY"?? Imagine a .Net type not USUAL (ex a Grid Column), What happens in these?
In FoxPro all variables could have the value null. I propose you something: review the .NET documentation https://docs.microsoft.com/en-us/dotnet/api/system.nullable-1?view=net-6.0 to try to stay closer and I think that FoxPro approach is really closer.
Juan,
There is no need to lecture me about the meaning of null in .Net.
I am fully aware of what it is and I am also aware that .Net has added the ability to declare things as nullable.
The various NULL* declarations in the X# were added because these existed in Visual Objects. They may look a bit weird to you but we had to support them to support Visual Objects. Most of these are simply casts to a certain type of the .Net null reference. NULL_DATE is an exception because DATE is a structure, so it maps to the date value 00-00-0000.
I think the FoxPro .Null. is probably best compared to NIL in the dialects that inherit from Clipper (like VO, Xbase++, Harbour).
But FoxPro has added SQL like behavior to .NULL., that is why we decided to not map .NULL. to NIL.
For example in the Clipper related languages 42 + NIL returns an error. In FoxPro 42 + .NULL. returns .NULL..
So we decided to invent a new type of USUAL. A USUAL with a value that represents a FoxPro .NULL..
Since SQL results can also return NULL and since this is represented in .Net with DBNull.Value, we have decided to (ab)use that value to represent .NULL..
Your comments and examples that FoxPro treats NULL like .NULL. came as a surprise to me. This is not documented and I had not seen this before. I have only see FoxPro use NULL inside SQL statements.
It will be a challenge to support that, but we'll find a way, I am sure.