Ken Takata wrote:

> 2016/7/30 Sat 5:38:42 UTC+9 Bram Moolenaar wrote:
> > Patch 7.4.2120
> > Problem:    User defined functions can't be a closure.
> > Solution:   Add the "closure" argument. Allow using :unlet on a bound
> >             variable. (Yasuhiro Matsumoto, Ken Takata)
> > Files:      runtime/doc/eval.txt, src/testdir/test_lambda.vim, 
> > src/userfunc.c,
> >             src/eval.c src/proto/userfunc.pro
> 
> I had a report that this patch doesn't work as expected:
> 
>       function! Foo()
>         let x = 0
>         function! Bar() closure
>           let x += 1
>           return x
>         endfunction
>         return function('Bar')
>       endfunction
>       
>       let Count = Foo()
>       echo Count() " => 1
>       echo Count() " => 2
>       echo Count() " => 3
>       
>       let Count2 = Foo()
>       echo Count() " => 1  (Should be 4)

Calling Foo() creates a new context in which "x" is set to zero.
And a new Bar() is created that uses this "x".  It should not re-use the
existing Bar(), it is still in use, being referenced.

Thus where it says:  /* redefine existing function */
It should leave that function alone and create a new one.  But the new
Bar() must be the one that's found in the global scope.  Thus it's a mix
of defining a new function and replacing an existing one.

> The function Bar() should have been handled like a lambda function which means
> reference counting is needed.
> Using a dict function with closure works as expected:
> 
>       function! Foo()
>         let x = 0
>         let d = {}
>         function! d.Bar() closure
>           let x += 1
>           return x
>         endfunction
>         return d.Bar
>       endfunction
> 
> (But this might be not so useful.)
> I don't have a good idea to fix this problem. Current idea is:
> 
> * "function! Bar() closure" creates an unnamed function with the internal name
>   "<lambda>N", and
> * The Funcref is assign to a local variable "Bar".
> 
> Not sure this goes well...

-- 
Lawmakers made it obligatory for everybody to take at least one bath
each week -- on Saturday night.
                [real standing law in Vermont, United States of America]

 /// Bram Moolenaar -- [email protected] -- 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 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

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui