Ernie Rael wrote:
> >> I saw some recent msgs about comparing anything to null, and that it
> >> would be allowed. I guess I got the wrong impression. Using vim:
> >> "Included patches: 1-4507"
> >>
> >> In my first vim9 script, I did (the real code conditionally return null)
> >>
> >> def Get(): string
> >> =C2=A0=C2=A0=C2=A0 return null
> >> enddef
> >>
> >> And this doesn't compile because "Type mismatch; expected string but got
> >> special".
> >>
> >> Allowing null seems like an improvement.
> > I am still looking into how we should use null. In many places null is
> > handled the same as an empty string. In this example you might as well
> > return an empty string, since it will be the same for most purposes.
> >
> > There are also complications, such as when assigning null to a variable,
> > when getting that value it looks like the variable wasn't initialized,
> > so it will be initialzed then and when it is a list, get an empty list
> > instead of null. That might be confusing.
>
> It seems the idea of reading a null variable, except when comparing, gives
> an empty item is OK, but since I haven't tried coding with it...
>
> I said empty item is OK except when comparing. But, assuming a null string,
> what about when compariing to something other than null? For example
>
> if sval == ''
>
> is that true or false when sval is null? I'd say true, which feels
> consistent with the idea of null representing an empty item and
>
> if sval == null
>
> is true if and only if when sval is null. The comparison explicitly to null
> would be the only way to detect null vs empty. This would seem to avoid the
> java-NPE type issues. There seems to be little opportunity for confusion.
If we consider an empty string equivalent to null, then both if these
should return true:
if sval == ''
if sval == null
If you want to check the difference, you would use "is":
if sval is null
This only works for null, since an empty string will be a different
instance every time.
On the other hand, there is a difference between null and a string with
value null. The latter has the string type, which matters in several
places. I'm not sure using null itself is a good idea. Your example at
the end of the message shows that you actually want a string with null
value, which in this case is to be considered different from an empty
string.
We actually have these values, such as with test_null_string(). These
were thought only to be useful for testing, but perhaps we should alow
for using them generally?
Another request was to be able to clear a script-local variable.
Assigning null would be one solution:
var F: func
var work: job
...
F = null
work = null
Currently this fails. And there is no way to clear "F" or "work". If
we make this work by actually assigning null to "F" and "work", then the
type is lost. What we probably want is something like:
F = test_null_function()
work = test_null_job()
That clears the variable without dropping the type. Same for your case
of wanting to have a string with null value:
d = {a: 'text', b: test_null_string()}
That way the type of the dictionary is clearly dict<string>. If we
would use:
d = {a: 'text', b: null}
Then the type is dict<any>, since we don't know what type the null
stands for, could be anything.
> > Also, a null list cannot store a type, because the type is kept on the
> > list. Not sure if this matters, since this only matters for declared
> > variables, which, as just mentioned, are initialized to an empty
> > list/dict/etc., and then the type is added.
I just tried this, and it seems to work OK. The type is also stored
with the variable, and it looks like that is used when needed.
> This means that assigning null to a structured item looses the previous
> type of the contents. I'm not familiar enough with vim9 to have an
> opinion or feeling as to what issues might arise, but...
Yes, that is the problem we need to tackle. Considering the above, how
about introducing different null types:
null_string
null_dict
null_list
null_function
null_partial
null_channel
null_job
That will allow for clearing a script-local variable, while keeping the
type. And it allows for using a null value in a dict or list while
keeping the type.
Another example, consider preparing a list with jobs, but the jobs have
not been created yet:
var jobs = {read: null_job, write: null_job, check: null_job}
...
jobs.read = job_start(...)
if writing
jobs.write = job_start(...)
endif
jobs.check = job_start(...)
...
if jobs.write != null_job
# write
endif
This looks better than just using "null" and handling the type
difference in some way.
Another problem not mentioned yet: When using a default value for a
function argument, and the type is channel, there was no value that
could be used. null_channel would be useful there too.
> BTW, it is disconcerting that "string sval" or "list<string> l_sval" does
> not work :-) But var works pretty well and it doesn't seem to be and issue.
There are different ways to do declarations in various languages. Using
"var" is similar to JavaScript and happens to fit well with Vim
commands.
--
If Microsoft would build a car...
... You'd have to press the "Start" button to turn the engine off.