Describe the bug
In Vim9 script, the is comparison operator cannot be used to compare arbitrary types of operands at the script level.
To Reproduce
Run this shell command:
vim -Nu NONE -S <(cat <<'EOF'
vim9script
var x: any
x = ''
eval x is 0
EOF
)
E1072 is raised:
E1072: Cannot compare string with number
Expected behavior
No error is raised.
Environment
Additional context
In a :def function, the exact same code doesn't raise any error:
vim9script def Func() var x: any x = '' eval x is 0 enddef Func()
no error
This seems inconsistent. If it works in a :def function, shouldn't it also work at the script level?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.![]()
Or maybe the issue is not at the script level, but in compiled code. Maybe this snippet should raise an error:
vim9script def Func() var x: any x = '' eval x is 0 enddef Func()
Not sure what the right choice is here. I think it would be convenient to be able to compare any types of operands with is and isnot. I have a few locations where I wrote something like this:
if typename(type) == 'string' && type == ''
If I had the guarantee that is will still be able to compare any types of operands in the future, be it at the script level or in compiled code, I would simplify these lines like this:
if type is ''
Some people agree, but not all. I wonder whether popular programming languages – with a type checking system – provide an extra set of comparison operators which don't raise an error when comparing operands with different types. That is, they first compare the types are identical, then the values.
I think javascript/typescript provide === which tests type equality and value equality, as well as !== which tests type inequality or value inequality. Maybe we should make is/isnot raise an error in compiled code, to be consistent with the script level; but also introduce the operators ===/!===?
The difference between script and compiled function is that in the script the actual type can be used. In compiled code the type from the expression is used, which is the type of "x" in this case. The assignment with a value isn't used there.
It's very hard to change this without introducing other problems. We could just accept any two types for "is", but then a comparison that will always fail won't generate an error. Since "is" is usually used to compare identity between Lists or Dicts, I think it's more useful to give the error than to permit everything. So let's leave it as is, even though it might seem inconsistent.
Closed #7931.