Can I rely on left to right evaluation?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Can I rely on left to right evaluation?

Bee-16
Can I rely on left to right evaluation?

Is there a problem with this phrase and the order of evaluation?

  @b + setreg('b', @l<n ? @b : @b+1 )

Is it a "tricky side effect semantics" as John Little warns?

Note: setreg() Returns zero for success

> Thanks to a suggestion in vim_use I have "grouped" line numbering working.
>
> It is not a normal sequential numbering, but in groups of n lines.
>
> Example n=2
> (    1_0_)
> (    1_1_)
> (    1_2_)
> (    2_0_)
> (    2_1_)
> (    2_2_)
> (    3_0_)
> (    3_1_)
> (    3_2_)
>
> vmap <F5> :<C-U>let n=15 <BAR> let @b=1 <BAR> let @l=0 <BAR>
>   \ '<,'>s/^/\=printf("( %4d_%X_)",
>   \ @b + setreg('b', @l<n ? @b : @b+1 ),
>   \ @l + setreg('l', @l<n ? @l+1 : 0 ))<cr>
> endif
>
> > On Jun 16, 10:06 pm, John Little <[hidden email]> wrote:
> > Please explain what you mean by the "tricky side effect semantics" as
> > I am learning.
>
> (Aren't we all?)   In the expression
>      @l + setreg('l', @l<str2nr(@n) ? @l+1 : 0 )
> the setting of the l register is a "side effect" of the evaluation of
> the expression, but the value of the expression could depend on this
> side effect.  If the expression is evaluated strictly left to right,
> the value of @l is taken and then changed, but if the setreg was done
> first the answer would be different.  The vim help says "All
> expressions within one level are parsed from left to right" but I
> could find no guarantee that it evaluates strictly left to right.
> Many languages, not least C and C++, explicitly prohibit such
> dependencies on the order of evaluation, though historically many
> compilers ignored them.

-Bill

--
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
Reply | Threaded
Open this post in threaded view
|

Re: Can I rely on left to right evaluation?

Tony Mechelynck
On 18/06/10 18:38, Bee wrote:
> Can I rely on left to right evaluation?
>
> Is there a problem with this phrase and the order of evaluation?
>
>    @b + setreg('b', @l<n ? @b : @b+1 )
>
> Is it a "tricky side effect semantics" as John Little warns?
>
> Note: setreg() Returns zero for success

Well, if setreg() returns zero for success, then that zero will be
returned after setting @b to @b+1. However, I expect that the old value
of @b may have been pushed onto the stack before that, so that the
expression will return the former value of @b. (Vimscript is an
interpreted language, not a compiled one; therefore I don't expect
"arithmetic optimization" to come into play.) But I might be wrong.

In this case I don't expect failure to be a possible outcome, so a
simpler (and also more predictable) command would be either

        :let b = @b += (@l >= n) | let whatever = b
or
        :let whatever = @b | let @b += (@l >= n)

depending on what you mean. Note that registers normally have a String
value. The above evaluates at least one register as a Number (two if
variable n holds a Number), which means that if the register is either
empty or does not start with a digit, it evaluates to zero. For instance
('bcd' + 1) evaluates to 1 and ('12qx' >= 5) evaluates to TRUE i.e. 1
(because 12 >= 5).


Best regards,
Tony.
--
Money is the root of all wealth.

--
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
Reply | Threaded
Open this post in threaded view
|

Re: Can I rely on left to right evaluation?

Bee-16
On Jun 18, 12:41 pm, Tony Mechelynck <[hidden email]>
wrote:

> On 18/06/10 18:38, Bee wrote:
> > Can I rely on left to right evaluation?
>
> > Is there a problem with this phrase and the order of evaluation?
>
> >    @b + setreg('b', @l<n ? @b : @b+1 )
>
> > Is it a "tricky side effect semantics" as John Little warns?
>
> > Note: setreg() Returns zero for success
>
> Well, if setreg() returns zero for success, then that zero will be
> returned after setting @b to @b+1. However, I expect that the old value
> of @b may have been pushed onto the stack before that, so that the
> expression will return the former value of @b. (Vimscript is an
> interpreted language, not a compiled one; therefore I don't expect
> "arithmetic optimization" to come into play.) But I might be wrong.

I think "arithmetic optimization" might be what John meant by "tricky
side effect semantics".

Using an old Mac PowerBook Pismo 500MHz and a file of about 20k lines.
vim numbers all 20k lines in about 3 seconds using this:

let lpb=15 "lines per block (zero based)

vmap <F5> :<C-U> let @b=1 <BAR> let @l=0 <BAR>
  \ '<,'>s/^/\=printf("( %4d_%X_)",
  \ @b + setreg('b', @l<lpb ? @b : @b+1 ),
  \ @l + setreg('l', @l<lpb ? @l+1 : 0 ))<cr>

John gave me a version written as a function,
and it is just as fast and simpler to understand.

let lpb = 15 "lines per block (zero based)
function! Renum()
  let g:b = 1
  let g:l = 0
  '<,'>s/^/\=ResInc()/
endfunction
function! ResInc()
  let result = printf('( %4d_%X_)', g:b, g:l)
  if g:l < g:lpb
    let g:l += 1
  else
    let g:l = 0
    let g:b += 1
  endif
  return result
endfunction
vmap <F4> :<c-u>call Renum()<cr>

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