Am 26.10.2015 um 19:38 schrieb Allin Cottrell:
On Mon, 26 Oct 2015, Sven Schreiber wrote:
> <hansl>
> open denmark # dummy dataset
>
> list lh = null
>
> if isnull(lh)
> print "yep" # doesn't get printed
> endif
> </hansl>
>
> I actually can understand conceptually that the list 'lh' is
"empty"
> rather than non-existing, but then I think either there should be this
> (new) keyword 'empty' for lists, or isnull(lh) should return True/1 in
> this case.
The above looks funny, I agree. However, it clearly corresponds to the
documentation of isnull():
"Returns 0 if name is the identifier for a currently defined object, be
it a scalar, a series, a matrix, list, string or bundle; otherwise
returns 1."
Is your suggestion that one should be able to say
list lh = empty # instead of "= null"
?
Perhaps this might be a solution, yes; see also below. I stumbled over
this in real life in the context of optional function arguments, cf. the
paragraph from the user guide:
"
Optional list arguments
If a list argument to a function is optional, this should be indicated
by appending a default value of null, as in
function scalar myfunc (scalar y, list X[null])
In that case, if the caller gives null as the list argument (or simply
omits the last argument) the named list X inside the function will be
empty. This possibility can be detected using the nelem() function,
which returns 0 for an empty list.
"
So the doc is absolutely correct and even consistent. However, the
syntax itself is confusing IMO. When you call this example function
myfunc() from the guide and omit the optional list argument, there is no
list X. But still isnull(X) will return 0.
This is in contrast to other optional argument types (as also correctly
explained in the doc), and this difference is probably the most
important issue here. Example:
<hansl>
function void noi(matrix *in[null])
if isnull(in)
print "yep" # get's printed!
endif
end function
noi()
</hansl>
The problem seems to be a semantic inconsistency between the "empty"
concept and the 'null' property in hansl across variable types. If you
mark a list argument as optional with [null], then nelem(X) == 0. But
try to compute nelem(in) in my example with the matrix, then gretl spits
out an error "undefined symbol 'in'"!
So yes, one solution could be:
- If an optional list argument is not provided in a function call, make
isnull(X) true there. Perhaps even raise an error on attempting nelem()
there.
- For an empty list in general, change the corresponding keyword from
"null" to "empty"; and an empty list would not be null, but of course
nelem(X) == 0.
- (How to deal with backwards compatibility, I don't know right now.)
And BTW, I just checked the situation with bundles, which is also
awkward and might need to distinguish between empty and null, too. See
this example to finish off an already long message:
<hansl>
function void nob(bundle *in[null])
if isnull(in) # true like with matrix type
print "yep" # get's printed!
endif
end function
nob()
bundle b2 = null
if isnull(b2) # false like with list type
print "b2 no" # not printed!
endif
</hansl>
thanks,
sven