2016-07-30 22:17 GMT+03:00 Bram Moolenaar <[email protected]>:
>
> 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 main problem is that “funcrefs” are not a funcrefs, they are
string keys that will be looked up in a hash with all functions.
extended-funcref was fixing this and a bit more: l̶a̶m̶b̶d̶a̶s̶
̶a̶n̶d̶ anonymous functions were no longer recorded in any global
hash, also allowed using Python callable objects as funcrefs. Do not
remember how I coped/planned to cope with using :function or something
else to print anonymous functions’ body, now I would simply suggest
`get(Fref, 'code')` which will return a list of strings or zero (e.g.
for Python functions), also `get(Fref, 'sid')`, `get(Fref, 'slnum')`
and `scriptpath(sid)` (last one has other use-cases, so `get(Fref,
'sid')`+`scriptpath(sid)` and not `get(Fref, 'sfile')`).

If interested, I can try and resurrect this patch in Neovim for
somebody else to port it to Vim. I am not planning to write such big
patches for Vim any more.

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

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