Address the issues with null described in #13458.
https://github.com/vim/vim/pull/13492
(12 files)
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
This snippet:
def F(x: any = null) enddef F()
raises:
E340: Internal error; if you can reproduce please report a bug
constant type 1 not supported
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
As well as this:
def G() var x: any = null enddef G()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Address the issues with null described in #13458.
It's unclear to me which issues this PR addresses. In particular, what is the null model that this issue implements? Some preliminary experiments indicate that (using list as an example) with this model, the variable a, b, c, d are the same in all comparisons using ==
var a: list<string>
var b: list<string> = null_list
var c: list<string> = null
var d: list<string> = []
To distinguish the "real" null items do: some_var is null_list
Distinguishing between an empty container and a null container seems important. To determine which containers are null, currently you can do
vim9script
var l: list<any> = [ null_dict, {}, null_list, [] ]
echo mapnew(l, (_, v) => v == null)
which ouputs the followin
[true, false, true, false]
indicating which elements in the input list are null.
With this PR's model, it looks like you need to do
# check if list elements are null, only for list/dict items
echo mapnew(l, (_, v) => {
if type(v) == v:t_dict
return v is null_dict
endif
if type(v) == v:t_list
return v is null_list
endif
throw "Not Handled"
})
A more practical example is checking if a function arg of type any is null, as seen in #13458 (comment). The logic, needing to first check the type before checking if is null, is the same.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I can't build at the moment so I just skimmed this.
Nullable value types seems like a significant change and at the risk of stating the obvious, it's not backwards compatible.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Added #13458 (comment) to original discussion.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
It seems it's not currently possible to distinguish null from the default values? If bool, number and float are to become nullable then they probably also need null_<type> values for consistency.
I noticed this bug, in passing. The following results in an error E1012: Type mismatch; expected special but got bool. This works on master.
vim9script var x = null x = null
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
(In awe of the evolution of this PR)
There's a difference between script/:def.
vim9script
var sv1 = null
echo typename(sv1)
def F1()
var fv1 = null
echo typename(fv1)
enddef
F1()
Expect function to report special, not number
special
number
The following gets a compilation error; incompatible with vim9.0.
Also, it could be useful/meaningful.
def F2(x: any = null)
enddef
E38: Null argument
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
(In awe of the evolution of this PR)
I couldn't work on this PR for the past few weeks. So the progress is slow.
There's a difference between
script/:def.
I will look into these issues.
vim9script var sv1 = null echo typename(sv1) def F1() var fv1 = null echo typename(fv1) enddef F1()Expect function to report
special, notnumberspecial numberThe following gets a compilation error; incompatible with vim9.0. Also, it could be useful/meaningful.
def F2(x: any = null) enddefE38: Null argument
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
(In awe of the evolution of this PR)
I couldn't work on this PR for the past few weeks. So the progress is slow.
In some ways that has made the progress all the more dramatic, and interesting, and awesome. I was initially unsure exactly what this PR was targeting. My confusion was due to the trailing "s" in "issues" from
Address the issues with null described in #13458.
And with each change it has come into focus. Silly me, the title
null ... same as ... null_<type> ... in assignment
says it all; exactly that and nothing more or less; complete backwards compatibility expected.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan pushed 2 commits.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
(In awe of the evolution of this PR)
There's a difference between
script/:def.vim9script var sv1 = null echo typename(sv1) def F1() var fv1 = null echo typename(fv1) enddef F1()Expect function to report
special, notnumberspecial numberThe following gets a compilation error; incompatible with vim9.0.
Also, it could be useful/meaningful.def F2(x: any = null) enddefE38: Null argument
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
It seems it's not currently possible to distinguish
nullfrom the default values? If bool, number and float are to become nullable then they probably also neednull_<type>values for consistency.
I noticed this bug, in passing. The following results in an error
E1012: Type mismatch; expected special but got bool. This works on master.vim9script var x = null x = null
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
The following gives a compilation error.
vim9script
def F(): list<string>
return null
enddef
F()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
@yegappan pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan pushed 2 commits.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan pushed 2 commits.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
This PR is ready now. I think I have covered most of the places where a null can be used to initialize a variable. If a few folks can try out the latest PR and report any issues, it will be helpful.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Thanks. I haven't looked at it but from Bram and Ernie's comments it seems this might not have been straight forward.
I'm not sure how much of #13458 is addressed by this PR but presumably these calls to job_getchannel produce the same error message.
var x: job = null echo job_getchannel(null) # => E1218: Job required for argument 1 echo job_getchannel(x) # => E916: Not a valid job
What's the motivation for making the simple types nullable and how do you test them?
var x: bool = null echo x == null # => false
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Some key points distilled from #13458
null_<type> are confusing.var x: list<string> = null can introduce new semantics.null_<type>.There seems to be at least loose consensus in #13458; but not many participants.
Only (1) is addressed by this PR; the current semantics and problems remain. Doing only (1) make it almost impossible to introduce new null semantics at a later date. IMHO, these issues should be addressed before any change is made (even if only to say "no, not going to do it, this is the way it is").
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
This PR is ready now. I think I have covered most of the places where a null can be used to initialize a variable. If a few folks can try out the latest PR and report any issues, it will be helpful.
@yegappan seems at least #13582 this one was not solved yet.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Some key points distilled from #13458
1. All the `null_<type>` are confusing. 2. An empty container should not equal null. 3. Using `var x: list<string> = null` can introduce new semantics. 4. A null container should not be usable as a value (except compare/assign). 5. Deprecate use of `null_<type>`.
There seems to be at least loose consensus in #13458; but not many participants.
Only (1) is addressed by this PR; the current semantics and problems remain. Doing only (1) make it almost impossible to introduce new null semantics at a later date. IMHO, these issues should be addressed before any change is made (even if only to say "no, not going to do it, this is the way it is").
@errael unless gave up null_<type> such things, otherwise it is different like null it is 2 things, it had designed like that, though i do not like null_<type>, so now IF it cannot give up that, then perhaps just help to make sure null_<type> work.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Thanks. I haven't looked at it but from Bram and Ernie's comments it seems this might not have been straight forward.
I'm not sure how much of #13458 is addressed by this PR but presumably these calls to
job_getchannelshould produce the same error message.
var x: job = null echo job_getchannel(null) # => E1218: Job required for argument 1 echo job_getchannel(x) # => E916: Not a valid job
The null literal is normalized when the lhs type is known. If the type is not known,
then the null value cannot be normalized. In the above case, when you assign
null to variable x of type job, the null value is converted to a null job value.
When you call the job_getchannel() function with a null value, the type is not
known during the type check phase and is known only at a very late stage.
I am wondering what is the use case for calling an internal function with a
literal null value.
What's the motivation for making the simple types nullable and how do you test them?
var x: bool = null echo x == null # => false
Any variable can be assigned a literal null value. Depending on the variable
type, the appropriate null value will be used. For a Boolean variable, the value
is false.
For simple types (number, bool and float), comparing against null will always
return false.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Some key points distilled from #13458
- All the
null_<type>are confusing.
- An empty container should not equal null.
- Using
var x: list<string> = nullcan introduce new semantics.
- A null container should not be usable as a value (except compare/assign).
- Deprecate use of
null_<type>.
There seems to be at least loose consensus in #13458; but not many participants.
Only (1) is addressed by this PR; the current semantics and problems remain.
The (2) item is also addressed. An empty container is not equal to null:
vim9script
var a: list<number>
echo a == null # false
var b: list<number> = []
echo a == null # false
var c: list<number> = null
echo c == null # true
For item (3), before this PR it is not possible to assign null to a container type.
But you can assign a type specific null_xxx value. After this PR, you can assign null
to achieve the same.
Item (4) is also addressed. You cannot add to a null container:
vim9script
var a: list<number> = null
add(a, [1]) # E1130: Cannot add to null list
We cannot remove the null_xxx values without breaking backward compatibility with Vim 9.0.
Doing only (1) make it almost impossible to introduce new null semantics at a later date. IMHO, these issues should be addressed before any change is made (even if only to say "no, not going to do it, this is the way it is").
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
This PR is ready now. I think I have covered most of the places where a null can be used to initialize a variable. If a few folks can try out the latest PR and report any issues, it will be helpful.
@yegappan seems at least #13582 this one was not solved yet.
The issue mentioned in #13582 is not related to using a null literal value.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
- Using
var x: list<string> = nullcan introduce new semantics.
For item (3), before this PR it is not possible to assign
nullto a container type. But you can assign a type specificnull_xxxvalue. After this PR, you can assignnull
Right. I'd say that's new syntax.
to achieve the same.
That's the problem. The semantics are the same; we have the same problems.
There is no way to have a null container. See following.
About (2) An empty container should not equal null.
vim9script
var r: list<number> = null
var s = []
echo r == s # true, but should be false
echo r == [] # true, but should be false
About (4)
vim9script
var z: list<number> = null
var y = z + [3] # z is null; shouldn't this be an error?
Posted some discussion about syntax for requesting new null semantics: #13458 (comment)
About (5) Deprecate use of null_<type>.
We cannot remove the
null_xxxvalues without breaking backward compatibility with Vim 9.0.
I understand. And I know there is currently no concept of "deprecate", let alone "deprectate with removal in the future". I guess the vim way is to mention in the documentation that there are new ways to do it.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
This PR is ready now. I think I have covered most of the places where a null can be used to initialize a variable. If a few folks can try out the latest PR and report any issues, it will be helpful. > > @yegappan seems at least #13582 this one was not solved yet. The issue mentioned in #13582 is not related to using a
nullliteral value.
it maybe required/missed a 'null_any' (or 'null_unknown') // that case typename of 'any' is 'number' should be wrong
…
-- shane.xb.qian
@yegappan as #13582 (comment) said, if that's intended, then please discard this comment.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
@yegappan pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Hm, I am confused. Is there a conclusion regarding @errael last comment: #13492 (comment)
?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
- Using
var x: list<string> = nullcan introduce new semantics.For item (3), before this PR it is not possible to assign
nullto a container type. But you can assign a type specificnull_xxxvalue. After this PR, you can assignnullRight. I'd say that's new syntax.
to achieve the same.
That's the problem. The semantics are the same; we have the same problems. There is no way to have a null container. See following.
About (2) An empty container should not equal null.
vim9script var r: list<number> = null var s = [] echo r == s # true, but should be false echo r == [] # true, but should be false
This cannot be addressed without breaking backward compatibility. See 7b293c7
Also, see https://github.com/vim/vim/blob/master/src/list.c#L378
About (4) A null container should not be usable as a value (except compare/assign).
vim9script var z: list<number> = null var y = z + [3] # z is null; shouldn't this be an error?
If this fails, then the user needs to check whether a variable is null before using it in
an expression. Consider, for example, a function that takes a List as an argument.
This could be a valid List or a null List or an empty List. Inside the function, before
using it in an expression, a null check will be needed. It will be simpler if we treat
a null container as an empty container.
Posted some discussion about syntax for requesting new
nullsemantics: #13458 (comment)
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Hm, I am confused. Is there a conclusion regarding @errael last comment: #13492 (comment)
?
This PR can be merged after the Vim 9.1 release (after concluding these discussions).
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Hm, I am confused. Is there a conclusion regarding @errael last comment: #13492 (comment)
?
the claim: var r: list<number> = null was not correct, a null cannot be assigned to a list<number>, so that following assumption also was not existed.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Hm, I am confused. Is there a conclusion regarding @errael last comment: #13492 (comment)
?
This PR can be merged after the Vim 9.1 release (after concluding these discussions).
i do not think so, if null and null_ to be equal, then it may break all existed vim9 script.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
This cannot be addressed without breaking backward compatibility. See 7b293c7
Currently var x: list<string> = null is an error. So if it happens, the compiler could tag x as a variable which uses new/familiar null semantics; in particular an empty container is different from a null container. But intuiting which null semantics to use could be confusing.
Probably better, and less confusing, would be a new way to declare a variable that has new/familiar null semantics as discussed in #13458 (comment).
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Hm, I am confused. Is there a conclusion regarding @errael last comment: #13492 (comment)
?
This PR can be merged after the Vim 9.1 release (after concluding these discussions).
i do not think so, if null and
null_<type>to be equal, then it may break all existed vim9 script.
Do you have an example use case where this will break backward compatibility?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Hm, I am confused. Is there a conclusion regarding @errael last comment: #13492 (comment)
?
This PR can be merged after the Vim 9.1 release (after concluding these discussions).
i do not think so, if null and
null_<type>to be equal, then it may break all existed vim9 script.Do you have an example use case where this will break backward compatibility?
simply to image, if it was equal, it would not raise err for the case e.g var r: list<number> = null,
or for instance in our lsp codebase to check 'feature' by null_string, if such was equal, then i can pass number or something else to it.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Also, see https://github.com/vim/vim/blob/master/src/list.c#L378
About (4) A null container should not be usable as a value (except compare/assign).
vim9script var z: list<number> = null var y = z + [3] # z is null; shouldn't this be an error?If this fails, then the user needs to check whether a variable is null before using it in an expression. Consider, for example, a function that takes a List as an argument. This could be a valid List or a null List or an empty List. Inside the function, before using it in an expression, a null check will be needed. It will be simpler if we treat a null container as an empty container.
The only languages I'm familiar with that have true null are Java and C/C++. It's up to the programmer to keep track of whether or not a variable is null. If it might be null, then yes you have to check.
Specifically about
before using it in an expression, a null check will be needed.
that depends on how well the programmer is keeping track of things. For example, a programmer could always define the container empty (and never null), which is the default in vim9script; then there is no need to ever check if it is null.
Since backwards compatibility is required, the only way to have "normal", or at least familiar, null semantics is to introduce a new way to get them without breaking the old way. That would seem to require a way to specify that a variable uses the new semantics.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
@yegappan pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Closed #13492.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Will reopen this PR after the 9.1 release.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()