[vim/vim] Vim9: cannot use "is" comparison operator to compare arbitrary types of operands at script level (#7931)

38 views
Skip to first unread message

lacygoill

unread,
Mar 4, 2021, 2:54:05 PM3/4/21
to vim/vim, Subscribed

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

  • Vim version: 8.2 Included patches: 1-2567
  • OS: Ubuntu 16.04.7 LTS
  • Terminal: xterm(366)

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.

lacygoill

unread,
Mar 5, 2021, 12:18:38 PM3/5/21
to vim/vim, Subscribed

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 ===/!===?

Bram Moolenaar

unread,
Mar 6, 2021, 12:01:57 PM3/6/21
to vim/vim, Subscribed

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.

Bram Moolenaar

unread,
Mar 6, 2021, 12:01:57 PM3/6/21
to vim/vim, Subscribed

Closed #7931.

Reply all
Reply to author
Forward
0 new messages