[vim/vim] Request for vim9: Cast to boolean implicitly (#6903)

23 views
Skip to first unread message

バクダンくん

unread,
Sep 7, 2020, 8:28:45 PM9/7/20
to vim/vim, Subscribed

Is your feature request about something that is currently impossible or hard to do? Please describe the problem.
The doc of vim9 says "Any type of variable can be used as a condition", but they cannot be assigned or returned as a boolean unless they are cast explicitly.
Moreover, every vim builtin functions returns 1 or 0 instead of a boolean, so you frequently need to cast them to boolean.
I wonder if this implicit casting will be implemented to vim9.

Following script works only when g:foo exists AND is v:true or v:false, otherwise E1029 is thrown.

def s:is_foo(): bool
  return exists('g:foo') && g:foo
enddef

echo s:is_foo()

Describe the solution you'd like
Cast any expressions to boolean implicitly.

Describe alternatives you've considered
!!(exists('g:foo') && g:foo) does work, but I feel it's redundant.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.

Bram Moolenaar

unread,
Sep 8, 2020, 1:27:59 PM9/8/20
to vim/vim, Subscribed

Yes, there is a balance to be found here between type-safety and convenience.
We have already made it so that when a function argument is true/false one can also use zero and one.
It is also unlikely that this leads to mistakes, so long as we don't accept other numbers.
bool flag = 1 # looks like true
bool flag = 99 # must be a mistake, type should be number
bool flag = -1 # not sure what the intention was here

For conditions it's clear that we need a true/false outcome. Here we could also be strict, but following Typescript, like we do in several other places, loose type checking makes it easier to write. This uses the concept of Truthy and Falsy. Personally I have a slight preference to be more strict, but keeping in line with Typescript is more important.

We do fix one inconsistency of Typescript: an empty string is Falsy while an empty list/array is Truthy. This is a mistake, probably based on historical reasons.

Bram Moolenaar

unread,
Sep 8, 2020, 1:41:22 PM9/8/20
to vim/vim, Subscribed

I didn't address your specific return statement. I wonder if we can say that if && or || is used, then the user clearly intends to get a boolean result, thus we can allow for automatic conversion to a bool type.
Not sure how to implement that though. Could probably make it work in compiled code, but we also need to be able to do this in Vim9 script. Hmm, perhaps we can use a flag in the v_lock field. Then we can do this:
let flag: bool = 99 # error!
let flag: bool = 'yes' # error!
let flag: bool = 99 && 'yes' # OK
Or is that going in the direction of being weird again?

Bram Moolenaar

unread,
Sep 9, 2020, 8:56:33 AM9/9/20
to vim/vim, Subscribed

Closed #6903 via 29a86ff.

puremo...@gmail.com

unread,
Sep 9, 2020, 9:22:23 AM9/9/20
to vim_dev
Python's take on this is that if you want a bool, you use the bool constructor `bool( <expr> )`; we could add a vimscript function (like `string`) which takes an expr and returns either `v:true` or `v:false`, as in `return bool( 'string' )` or `return bool( 99 )`. The semantics of the type specified would have to determine how 'truthy' a value is. I think that's already defined for vimscript as mentioned.

バクダンくん

unread,
Sep 9, 2020, 10:03:08 AM9/9/20
to vim/vim, Subscribed

Thank you! Sounds good solution!

Bram Moolenaar

unread,
Sep 9, 2020, 2:59:34 PM9/9/20
to vim...@googlegroups.com, puremo...@gmail.com

> Python's take on this is that if you want a bool, you use the bool
> constructor `bool( <expr> )`; we could add a vimscript function (like
> `string`) which takes an expr and returns either `v:true` or `v:false`, as
> in `return bool( 'string' )` or `return bool( 99 )`. The semantics of the
> type specified would have to determine how 'truthy' a value is. I think
> that's already defined for vimscript as mentioned.

We already have the "!!" operator which most likely does the same thing.
Anyone writing Javascript or Typescript is common with using this.

Using bool() would also work, but I don't see a good reason to add
a second way. We don't have much similarity with Python for
expressions.

As mentioned before, some users expect an expression like
"'yes' || 'no'" to result in "true" when used for a bool, like in a
condition of :if or :while. I'm right now implementing that, and it
looks like it will work and feels natural.

Without "||" or "&&" you would still need to use "!!", which makes
sense, since using a string or number for a boolean value looks like a
mistake.

--
MONK: ... and the Lord spake, saying, "First shalt thou take out the Holy Pin,
then shalt thou count to three, no more, no less. Three shalt be the
number thou shalt count, and the number of the counting shalt be three.
Four shalt thou not count, neither count thou two, excepting that thou
then proceed to three. Five is right out. Once the number three, being
the third number, be reached, then lobbest thou thy Holy Hand Grenade of
Antioch towards thou foe, who being naughty in my sight, shall snuff it.
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages