Replies: 24 comments 12 replies
-
As explained in the help for |
Beta Was this translation helpful? Give feedback.
-
I've wondered about this myself.
I don't see that, consider
The above fails; it doesn't seem like it should; it's not ambiguous; the type of
like There may be cases where these type specific nulls are needed, I haven't looked deeply enough, but the language could be I definitely think null in the language could be improved, but all these varieties of null are part of vim9.0. so I don't think you can just get rid of them. |
Beta Was this translation helpful? Give feedback.
-
Related to #11770. There I suggested that, if “typed nulls” have to be kept, they should be disallowed at least in comparisons. But, imo, the semantics of nulls should be carefully revised. The main problem I see with “typed nulls” is that they stand for a missing value and for an empty (but defined) value at the same time. That seems to me like walking on a razor's blade. Some (non-exhaustive) random weirdness: (1)
echo null == null_string # true
echo "" .. null == "null" # true, special is cast to string
echo "" .. null_string == "" # true, null_string is “the same” as an empty string
(2)
echo null == null_list # true
echo [] + null # E745: using List as Number
echo [] + null_list = [] # true, null_list is “the same” as an empty list
(3)
var x: string
echo x == null # true
echo x == null_string # true
echo x == "" # true
(4)
var x: string = null_string
echo x == null # true
echo x == null_string # true
echo x == "" # true
(5)
var x: string = ""
echo x == null # false
echo x == null_string # true
echo x == "" # true
(6)
var x: list<string>
echo x == null # false
echo x == null_list # true
echo x == [] # true
(7)
echo extend([], null_list) # 0 (error?), but:
echo [] == null_list # true
echo extend({}, null_dict) # 0 (error?), but:
echo {} == null_dict # true (I think those with |
Beta Was this translation helpful? Give feedback.
-
You can do: var x: list<string> = null_list
echo x == null # true But then, also these are true: echo x == null_list # true
echo x == [] # true |
Beta Was this translation helpful? Give feedback.
-
I'm aghast (not to mention dumbfounded) and wondering how I missed this (or maybe I forgot about it).
So never, ever use a "typed null" in a comparison, if you want your code to make sense. I wonder if
could be made to work, such that it sets a typed variable
works as expected. [Corrected example 2023 Oct 31] I think this would obviate the need for typed nulls. Then proper null semantics would be available. They could legitimately be deprecated or just left_around if you want to use Do you (anyone) think that handling I wonder if the "typed null" is all about implementation issues, not language coherence.
It would be good to do something. |
Beta Was this translation helpful? Give feedback.
-
Yeah, fixing those wouldn't seem to cross the compatibility boundary. |
Beta Was this translation helpful? Give feedback.
-
Not a good idea, too many implementation issues. IGNORE THIS POST
An uninitialized type has the well known default value, primitives are zero (or close to it) containers are empty. For example the two declarations in the following are equivalent.
Any item can be set to null
A variable always has a type
A null variable can only be compared or assigned; any other use is an error. For example
Details have to be specified. Guessing: specialized types, like After reading this discussion, I've lost my blissful ignorance. I'm still a little confused about the current Warnings and/or lint would be useful in transitioning to a new |
Beta Was this translation helpful? Give feedback.
-
Looking for a fix for #13433, it looks like that problem resonates with this one. I think the proposed fix for that could be a basis for the fix as described in the previous post. I think the null stuff may be implemented the way it is because it was a late addition to vim9, and not fully integrated. |
Beta Was this translation helpful? Give feedback.
-
There look to be deeply ingrained implementation reasons why nulls are handled the way they are. In the dev forum, March of 2022, there's vim9script and null which gives insight into how the current model came about. Without considerable work, the current model remains; not sure how best to simplify understanding of how it works. Use
It does seem that usually you can stick with If a variable is assigned For example, def F(arg: any)
if arg == null # cannot use null_<type>; type could be "list" or "dict" or ...
...
endif
...
enddef Another example, some_list->filter((_, val) => val != null) |
Beta Was this translation helpful? Give feedback.
-
I have created the draft PR #13492 to address the issues with null described in this issue. Please try this PR out. |
Beta Was this translation helpful? Give feedback.
-
From the discussion, it seems like a combination of implementation convenience and a dubious assertion that the difference between null and an empty value is meaningless.
I think they're best conceptualised as a tagged default value that can be compared against null. It's an unusual language that even initialises local variables to the default value so I guess this can be viewed as being in keeping with that principle. I find this sort of line in the help a bit disconcerting as a user: "Quite often a null value is handled the same as an empty value, but not always." I thought they were some sort of implicit intersection type but there is no dedicated null type. Perhaps it should be discussed in the help more in the context of being a shade-tree null-safety model? I'm not sure how much there is to be fixed here at the moment, obvious bugs aside, but it might be wise to keep open the possibility of adding a better null-safety implementation in the future rather than make minor improvements to this model. And they said legacy script was confusing... 😄 |
Beta Was this translation helpful? Give feedback.
-
Tried a few things, comments with the PR. |
Beta Was this translation helpful? Give feedback.
-
Hoping this discussion can restart from a clean slate... Implementation is not considered other that to note there is a current implementation which mostly works. (list is used in examples) Summarizing this discussion and the spec.
Problems
What to do nowLet's hear from everybody about null spec issues. Especially @dkearns, @yegappan, @lifepillar, @Rhialto And especially about the downside of "Equality is not transitive (when nulls are involved)"? Example? Notes
[1] vim9script's null handling evolution |
Beta Was this translation helpful? Give feedback.
-
Although the current null semantics are messy, they work (maybe some bugs). IMHO, don't open the can of worms, try to replace it; or as @dkearns said in summary of #13458 (comment)
Better documentation might help. |
Beta Was this translation helpful? Give feedback.
-
additional Thinking about adding some documentation near This 5 point outline takes the first two points from the Notes in #13458 (comment), followed by a few more points
(4) and (5) above are presented as two ways the programmer can work with null comparison; they may be controversial. As outlined above, the documentation is based on the current code; and so may change depending on how #13492 is resolved. Here are some results checking compare performance. Mostly as expected. I was a initially surprised that
|
Beta Was this translation helpful? Give feedback.
-
Not sure if there's interest in more help on null behavior...
|
Beta Was this translation helpful? Give feedback.
-
There certainly is, and thanks for offering, but it would be sensible to wait until it's fully specified. The existing documentation is far from Vim's normally excellent standards and I don't think it's possible to fully understand how null is currently handled in the language without experimentation. Edit: Hadn't noticed YL's recent post.
I assume there's at least some tacit agreement that the existing model, and not just implementation, is poor? I think it's currently serviceable, some null-like value can be assigned for each reference type and reliably checked for with At a minimum I'd like to see Yegappan's great work in #13492 use null assignment to deprecate the empty-like value semantics and actually assign More generally, it's becoming hard to justify even this sort of hand-wavy bottom type model for a language designed with hindsight of the last thirty years. I think nullable types, as implemented in some fashion by Kotlin, C#, Dart, and Java, among others, would be a good fit and could probably be implemented incrementally. Even being able to just specify the types that are nullable would be progress. In regards to #11770, and similar issues, my view is as at least as strong as LifePillar's, "Fundamental mathematical properties such as transitivity of equality should not be violated." I, uncomfortably, disagree with Bram's assessment there and think the current implementation is causing "obscure problems" and find it unlikely that anyone is relying on that behaviour. |
Beta Was this translation helpful? Give feedback.
-
On Mon, Nov 20, 2023 at 12:08 PM dkearns ***@***.***> wrote:
More generally, it's becoming hard to justify even this sort of hand-wavy
bottom type model for a language designed with hindsight of the last thirty
years. I think nullable types, as implemented in some fashion by Kotlin,
C#, Dart, and Java, among others, would be a good fit and could probably be
implemented incrementally. Even being able to just specify the types that
are nullable would be progress.
issues, my view is as at least as strong as LifePillar's, "Fundamental
mathematical properties such as transitivity of equality should not be
violated." I, uncomfortably, disagree with Bram's assessment there and
think the current implementation is causing "obscure problems" and find it
unlikely that anyone is relying on that behaviour.
I made a similar comment about Option types, but nullables (and perhaps
associated occurrence typing so that types under null checks make sense)
might be a way to do this without needing pattern matching and other
machinery.
Perhaps it would be useful to work up some "desired" example programs and
their semantics, and figure out how to make the implementation match that?
Rather than start from one implementation and duct-tape it?
… —
Reply to this email directly, view it on GitHub
<#13458 (comment)>,.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to a topic in the
Google Groups "vim_dev" group.
To unsubscribe from this topic, visit
https://groups.google.com/d/topic/vim_dev/JZ_BC4tYotU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to
***@***.***
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/vim/vim/repo-discussions/13458/comments/7621864%40github.com
<https://groups.google.com/d/msgid/vim_dev/vim/vim/repo-discussions/13458/comments/7621864%40github.com?utm_medium=email&utm_source=footer>
.
--
D. Ben Knoble
|
Beta Was this translation helpful? Give feedback.
-
I'm not sure I understand. Are you saying to recommend use null in assignments as part of deprecating
What's the rationale for adding "optional" or "nullable" (hadn't seen It looks like you're saying additional null safety could be added in the future in a backwards compatible way. |
Beta Was this translation helpful? Give feedback.
-
If I wasn't vociferous about it then I must have trying to stop pissing people off. I'd recommend a null model for 9.1 that uses Primitive and container and specialized types have slightly different initialization semantics (has nothing to do with I was considering suggesting an error if |
Beta Was this translation helpful? Give feedback.
-
Yes. E.g., in the following var x: list<any> = null
echomsg len(x) # => 0
echomsg len(null) # => Error
var y: list<any> = null_list
echomsg len(y) # => 0
echomsg len(null_list) # => 0
That's pretty much the same argument that landed the language in this mess. Only having to reason about null when it's required simplifies the language usage by some measure. Oberon, Scheme, and dare I say it, Lua, are small languages. Vim9 script is not a small language. I wish it was, but every argument made for simplifying it has failed to gain traction.
The same problem it's been in every language that's ever implemented it in this manner.
I think it could be with a flag to
While Vim9 script hasn't seen the sort of take-up we might have hoped for, a quick search of GitHub suggests that there's enough |
Beta Was this translation helpful? Give feedback.
-
I thought it was "implementation convenience" as you noted earlier.
Better the devil you know?
That doesn't seem workable, unless maybe you mean per file. Using syntax like |
Beta Was this translation helpful? Give feedback.
-
I was referring more to Bram's comment "When do you need to know whether a string is really null or empty? That should be rare." Most of the problems I see in the language, as a user, seem to result from an attempt to "dumb down" features as a reaction against its arguably excessive scope.
The old devil is certainly better than the new but I prefer unicorns, or at least a donkey sporting a party hat.
Yes, and presumably a per package configuration would be useful. Some languages, C# included, also offer sub-file region granularity. Unfortunately, it's not possible to easily evolve the language over time given Vim's strict backward compatibility requirements. This discussion thread was prompted by me actually suffering at the hands of the current implementation. I noticed I'd missed a null check, because I'm a terrible programmer, and wondered why my plugin hadn't exploded. This was apparently the first time I'd had to deal with null in Vim9 script. I wrote quite a lot of it about eighteen months ago but hadn't had to look into the abyss until recently. |
Beta Was this translation helpful? Give feedback.
-
The tricky part of providing new and familiar It's possible to determine old or new semantics according to usage, There was mention of
Another possibility: instead of |
Beta Was this translation helpful? Give feedback.
-
Can anyone explain the need for these values? This seems rather horrifying at first blush, I'm not sure why I've never noticed before. Is there really no sane way to integrate null into the type system?
Beta Was this translation helpful? Give feedback.
All reactions