[vim/vim] Add support for conditional assignment using ?= (#4695)

28 views
Skip to first unread message

Yegappan Lakshmanan

unread,
Jul 19, 2019, 1:56:02 AM7/19/19
to vim/vim, Subscribed

I have ported the diff sent by Dave Eggum in 2006 to add support
for conditional assignment using ?=.

The following item in the todo list refers to this:

  • Add ":let var ?= value", conditional assignment. Patch by Dave Eggum,
    2006 Dec 11.

The e-mail thread is here:

https://marc.info/?l=vim-dev&m=116591795423455&w=2


You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/4695

Commit Summary

  • Add support for conditional assignment

File Changes

Patch Links:


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

Christ van Willegen

unread,
Jul 19, 2019, 2:31:04 AM7/19/19
to vim...@googlegroups.com, reply+ACY5DGBXJBJ76QQEBT...@reply.github.com
Hi, 

Op vr 19 jul. 2019 07:56 schreef Yegappan Lakshmanan <vim-dev...@256bit.org>:

I have ported the diff sent by Dave Eggum in 2006 to add support
for conditional assignment using ?=.

The following item in the todo list refers to this:

  • Add ":let var ?= value", conditional assignment. Patch by Dave Eggum,
    2006 Dec 11.
There are one or two places in the patch that include code or comments that implements the .= operator. 

Is that intentional?

Christ van Willegen

vim-dev ML

unread,
Jul 19, 2019, 2:31:33 AM7/19/19
to vim/vim, vim-dev ML, Your activity
Hi,

Op vr 19 jul. 2019 07:56 schreef Yegappan Lakshmanan <
vim-dev...@256bit.org>:

> I have ported the diff sent by Dave Eggum in 2006 to add support
> for conditional assignment using ?=.
>
> The following item in the todo list refers to this:
>
> - Add ":let var ?= value", conditional assignment. Patch by Dave Eggum,
> 2006 Dec 11.
>

> There are one or two places in the patch that include code or comments
that implements the .= operator.

Is that intentional?

Christ van Willegen

>

Yegappan Lakshmanan

unread,
Jul 19, 2019, 2:39:25 AM7/19/19
to vim_dev, reply+ACY5DGBXJBJ76QQEBT...@reply.github.com
Hi,
Which part of the diff are you referring to? All the changes in the diff
are related to "?=".

Regards,
Yegappan

vim-dev ML

unread,
Jul 19, 2019, 2:40:05 AM7/19/19
to vim/vim, vim-dev ML, Your activity
Hi,

On Thu, Jul 18, 2019 at 11:31 PM Christ van Willegen
<cvwil...@gmail.com> wrote:
>
> Hi,
>
> Op vr 19 jul. 2019 07:56 schreef Yegappan Lakshmanan <vim-dev...@256bit.org>:
>>
>> I have ported the diff sent by Dave Eggum in 2006 to add support
>> for conditional assignment using ?=.
>>
>> The following item in the todo list refers to this:
>>
>> Add ":let var ?= value", conditional assignment. Patch by Dave Eggum,
>> 2006 Dec 11.
>
> There are one or two places in the patch that include code or comments that implements the .= operator.
>

Which part of the diff are you referring to? All the changes in the diff
are related to "?=".

Regards,
Yegappan

> Is that intentional?
>
> Christ van Willegen
>

K.Takata

unread,
Jul 19, 2019, 2:43:51 AM7/19/19
to vim/vim, vim-dev ML, Comment

@k-takata commented on this pull request.


In src/eval.c:

> @@ -1487,8 +1488,8 @@ ex_let_const(exarg_T *eap, int is_const)
  * Assign the typevalue "tv" to the variable or variables at "arg_start".
  * Handles both "var" with any type and "[var, var; var]" with a list type.
  * When "nextchars" is not NULL it points to a string with characters that
- * must appear after the variable(s).  Use "+", "-" or "." for add, subtract
- * or concatenate.
+ * must appear after the variable(s).  Use "+", "-", "." or "?" for add,
+ * subtract concatenate or conditionally assign.

s/subtract/subtract,/


You are receiving this because you commented.

Codecov

unread,
Jul 19, 2019, 3:11:14 AM7/19/19
to vim/vim, vim-dev ML, Comment

Codecov Report

Merging #4695 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@

##           master    #4695      +/-   ##

==========================================

+ Coverage   81.35%   81.35%   +<.01%     

==========================================

  Files         114      114              

  Lines      145212   145219       +7     

==========================================

+ Hits       118130   118136       +6     

- Misses      27082    27083       +1
Impacted Files Coverage Δ
src/eval.c 86.34% <100%> (+0.02%) ⬆️
src/profiler.c 92.69% <0%> (-0.57%) ⬇️
src/gui_gtk_x11.c 57.86% <0%> (-0.1%) ⬇️
src/window.c 87.33% <0%> (-0.04%) ⬇️
src/term.c 79.16% <0%> (+0.05%) ⬆️
src/if_xcmdsrv.c 86.17% <0%> (+0.53%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7964873...0521dc1. Read the comment docs.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

FUJIWARA Takuya

unread,
Jul 19, 2019, 4:20:55 AM7/19/19
to vim/vim, vim-dev ML, Comment

I usually use get() for this purpose.

let default_value = 42
let g:myplugin_globalvar = get(g:, 'myplugin_globalvar', default_value)

I think get() is enough, but if someone wants this patch,
I want also binary operator for consistency.

let a ?= b
let a = a ? b

It doesn't work (because ? is already used for ternary operator a ? b : c).
so I would like to propose ??=.

let a ??= b
let a = a ?? b


You are receiving this because you commented.

mattn

unread,
Jul 19, 2019, 4:25:03 AM7/19/19
to vim/vim, vim-dev ML, Comment

Do not merge this.

if !exists("foo")
  let foo = "bar"
endif

This documentation is NOT right. This implementation is:

let tmp = "bar"
if !exists("foo")
  let foo = tmp
endif
unlet tmp

For example, if the RHS (right-hand-side) is calling function, the function is always evaluated even if the operator is "?=".

let foo ?= s:bar()

Because this syntax is below.

let tmp = s:bar()
if !exists("foo")
  let foo = tmp
endif
unlet tmp

i.e. Current implementation does not skip right-hand-side. The 4th argument of set_var_lval is passed as already evaluated value when the set_var_lval will be called. If you want to implement this as your expected, the RHS must not be evaluated.

function s:update()
  let s:foo = 2
  return s:foo
endfunction

"let s:foo = 1
let s:foo ?= s:update()

You need to change all of the part calling set_var_lval.


You are receiving this because you commented.

Bram Moolenaar

unread,
Jul 19, 2019, 6:18:21 AM7/19/19
to vim/vim, vim-dev ML, Comment


> I usually use `get()` for this purpose.

I also wonder if adding ?= is useful enough. Most languages don't
support this. Wikipedia only mentions its use in regexp.

> ```vim

> let default_value = 42
> let g:myplugin_globalvar = get(g:, 'myplugin_globalvar', default_value)
> ```
>
> ---

>
> I think `get()` is enough, but if someone wants this patch,
> I want also binary operator for consistency.
>
> ```vim

> let a ?= b
> let a = a ? b
> ```
>
> It doesn't work (because `?` is already used for ternary operator `a ? b : c`).
> so I would like to propose `??=`.
>
> ```vim

> let a ??= b
> let a = a ?? b
> ```

Isn't that ?:, the Elvis operator?

--
A special cleaning ordinance bans housewives from hiding dirt and dust under a
rug in a dwelling.
[real standing law in Pennsylvania, United States of America]

/// 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 ///


You are receiving this because you commented.

FUJIWARA Takuya

unread,
Jul 19, 2019, 6:44:53 AM7/19/19
to vim/vim, vim-dev ML, Comment

@brammool

Isn't that ?:, the Elvis operator?

Ah sorry, firstly I see this PR,
I thought let a ?= b is same as let a = a ? a : b (like elvis operator).
My ?? proposal is based on the misunderstanding 😓

In my conclusion, I think ?= is not necessary after all.

Christ van Willegen

unread,
Jul 20, 2019, 9:28:40 AM7/20/19
to vim...@googlegroups.com, reply+ACY5DGBXJBJ76QQEBT...@reply.github.com
Hi Yegappan,

On Fri, Jul 19, 2019 at 8:39 AM Yegappan Lakshmanan <yega...@gmail.com> wrote:
> On Thu, Jul 18, 2019 at 11:31 PM Christ van Willegen
> <cvwil...@gmail.com> wrote:
> >
> > Hi,
> >
> > Op vr 19 jul. 2019 07:56 schreef Yegappan Lakshmanan <vim-dev...@256bit.org>:
> >>
> >> I have ported the diff sent by Dave Eggum in 2006 to add support
> >> for conditional assignment using ?=.
> >>
> >> The following item in the todo list refers to this:
> >>
> >> Add ":let var ?= value", conditional assignment. Patch by Dave Eggum,
> >> 2006 Dec 11.
> >
> > There are one or two places in the patch that include code or comments that implements the .= operator.
> >
>
> Which part of the diff are you referring to? All the changes in the diff
> are related to "?=".

I was thrown off by these lines:

- if (*expr != '=' && !((vim_strchr((char_u *)"+-*/%", *expr) != NULL
+ if (*expr != '=' && !((vim_strchr((char_u *)"+-*/%?", *expr) != NULL
&& expr[1] == '=') || concat))

(That I now see totally misread! I just went "Oooh" when I revisited the patch).

I _thought_ that the original code did not use the '|| concat' in the
second line. I totally missed that there was no + in fron of it, so I
thought it was a change with respect to the original code.

Also, I misread this:

- * must appear after the variable(s). Use "+", "-" or "." for add, subtract
- * or concatenate.
+ * must appear after the variable(s). Use "+", "-", "." or "?" for add,
+ * subtract, concatenate or conditionally assign.

Because the "." was originally after the 'or', I didn't see that it
was in the original code as well...

This should teach me to:

- Read the patch carefully
- Re-read the patch carefully
- Think
- Think harder
- Only _then_ complain on the mailing list about wrong code...

Christ van Willegen

vim-dev ML

unread,
Jul 20, 2019, 9:29:01 AM7/20/19
to vim/vim, vim-dev ML, Your activity
Hi Yegappan,

On Fri, Jul 19, 2019 at 8:39 AM Yegappan Lakshmanan <yega...@gmail.com> wrote:
> On Thu, Jul 18, 2019 at 11:31 PM Christ van Willegen
> <cvwil...@gmail.com> wrote:
> >
> > Hi,
> >
> > Op vr 19 jul. 2019 07:56 schreef Yegappan Lakshmanan <vim-dev...@256bit.org>:
> >>
> >> I have ported the diff sent by Dave Eggum in 2006 to add support
> >> for conditional assignment using ?=.
> >>
> >> The following item in the todo list refers to this:
> >>
> >> Add ":let var ?= value", conditional assignment. Patch by Dave Eggum,
> >> 2006 Dec 11.
> >

Bram Moolenaar

unread,
Jul 21, 2019, 8:49:00 AM7/21/19
to vim/vim, vim-dev ML, Comment

I find this operator rather obscure, I can't find it in popular languages.
Also, it's easy enough to use the "if" construct. It's more lines, but it's easier to understand.
I also haven't heard anyone ask for this, and suspect it won't be used much because plugin developers do not know it exists.
Keeping the Vim script language simple is more important, in my opinion.


You are receiving this because you commented.

Bram Moolenaar

unread,
Jul 21, 2019, 8:49:03 AM7/21/19
to vim/vim, vim-dev ML, Comment

Closed #4695.


You are receiving this because you commented.

Yegappan Lakshmanan

unread,
Jul 21, 2019, 11:44:24 AM7/21/19
to vim_dev, reply+ACY5DGG4XRYCB7EZ3U...@reply.github.com, vim/vim, vim-dev ML, Comment
Hi Bram,

On Sun, Jul 21, 2019 at 5:49 AM Bram Moolenaar
<vim-dev...@256bit.org> wrote:
>
> I find this operator rather obscure, I can't find it in popular languages.
> Also, it's easy enough to use the "if" construct. It's more lines, but it's easier to understand.
> I also haven't heard anyone ask for this, and suspect it won't be used much because plugin developers do not know it exists.
> Keeping the Vim script language simple is more important, in my opinion.
>

In that case, the following item needs to be removed from the todo list:

- Add ":let var ?= value", conditional assignment. Patch by Dave Eggum,
2006 Dec 11.

I found that only Ruby has an operator (||=) for the default assignment.
Other languages are referring to using the ternary operator for this.
In these cases, the operator is used only in the RHS expression.

- Yegappan

vim-dev ML

unread,
Jul 21, 2019, 11:44:48 AM7/21/19
to vim/vim, vim-dev ML, Your activity
Hi Bram,

On Sun, Jul 21, 2019 at 5:49 AM Bram Moolenaar
<vim-dev...@256bit.org> wrote:
>
> I find this operator rather obscure, I can't find it in popular languages.
> Also, it's easy enough to use the "if" construct. It's more lines, but it's easier to understand.
> I also haven't heard anyone ask for this, and suspect it won't be used much because plugin developers do not know it exists.
> Keeping the Vim script language simple is more important, in my opinion.
>

In that case, the following item needs to be removed from the todo list:

- Add ":let var ?= value", conditional assignment. Patch by Dave Eggum,
2006 Dec 11.

I found that only Ruby has an operator (||=) for the default assignment.
Other languages are referring to using the ternary operator for this.
In these cases, the operator is used only in the RHS expression.

- Yegappan

Yegappan Lakshmanan

unread,
Jul 21, 2019, 11:49:44 AM7/21/19
to vim_dev, reply+ACY5DGHHRQ5MHB272R...@reply.github.com, vim/vim, vim-dev ML, Comment
Hi,

On Fri, Jul 19, 2019 at 1:20 AM FUJIWARA Takuya
<vim-dev...@256bit.org> wrote:
>
> I usually use get() for this purpose.
>
> let default_value = 42
> let g:myplugin_globalvar = get(g:, 'myplugin_globalvar', default_value)
>

This example of using the get() function with the g: dictionary to get
either the current value or the default value of a variable should be
mentioned somewhere in the help.

Regards,
Yegappan

vim-dev ML

unread,
Jul 21, 2019, 11:50:10 AM7/21/19
to vim/vim, vim-dev ML, Your activity

Bram Moolenaar

unread,
Jul 21, 2019, 12:10:00 PM7/21/19
to vim...@googlegroups.com, Yegappan Lakshmanan, reply+ACY5DGG4XRYCB7EZ3U...@reply.github.com

Yegappan wrote:

> On Sun, Jul 21, 2019 at 5:49 AM Bram Moolenaar
> <vim-dev...@256bit.org> wrote:
> >
> > I find this operator rather obscure, I can't find it in popular languages.
> > Also, it's easy enough to use the "if" construct. It's more lines, but it's easier to understand.
> > I also haven't heard anyone ask for this, and suspect it won't be used much because plugin developers do not know it exists.
> > Keeping the Vim script language simple is more important, in my opinion.
> >
>
> In that case, the following item needs to be removed from the todo list:
>
> - Add ":let var ?= value", conditional assignment. Patch by Dave Eggum,
> 2006 Dec 11.

I'll remove that.

> I found that only Ruby has an operator (||=) for the default assignment.
> Other languages are referring to using the ternary operator for this.
> In these cases, the operator is used only in the RHS expression.

--
(letter from Mark to Mike, about the film's probable certificate)
For an 'A' we would have to: Lose as many shits as possible; Take Jesus
Christ out, if possible; Loose "I fart in your general direction"; Lose
"the oral sex"; Lose "oh, fuck off"; Lose "We make castanets out of your
testicles"
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

vim-dev ML

unread,
Jul 21, 2019, 12:10:24 PM7/21/19
to vim/vim, vim-dev ML, Your activity

Yegappan wrote:

> On Sun, Jul 21, 2019 at 5:49 AM Bram Moolenaar
> <vim-dev...@256bit.org> wrote:
> >
> > I find this operator rather obscure, I can't find it in popular languages.
> > Also, it's easy enough to use the "if" construct. It's more lines, but it's easier to understand.
> > I also haven't heard anyone ask for this, and suspect it won't be used much because plugin developers do not know it exists.
> > Keeping the Vim script language simple is more important, in my opinion.
> >
>
> In that case, the following item needs to be removed from the todo list:
>
> - Add ":let var ?= value", conditional assignment. Patch by Dave Eggum,
> 2006 Dec 11.

I'll remove that.

> I found that only Ruby has an operator (||=) for the default assignment.
> Other languages are referring to using the ternary operator for this.
> In these cases, the operator is used only in the RHS expression.

--
(letter from Mark to Mike, about the film's probable certificate)
For an 'A' we would have to: Lose as many shits as possible; Take Jesus
Christ out, if possible; Loose "I fart in your general direction"; Lose
"the oral sex"; Lose "oh, fuck off"; Lose "We make castanets out of your
testicles"
"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