2016-07-30 16:20 GMT+03:00 Ken Takata <[email protected]>:
> Hi,
>
> 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)
>
> 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...
This would again be fixed by extended-funcref branch (if it was
updated to work with current code base). In that branch funcref is a
pointer to the function structure, *not* a mere string with different
type tag attached (pointer to function is basically what a funcref is
in most other interpreted languages I have seen). So `function('Bar')`
references structure 1, next `function! Bar` creates structure 2, but
previous funcref *still* references structure 1 even though it is no
longer present in user functions hash. Basically function may be
written as
function MyPluginFoo()
let x = 0
function s:Bar() closure
let x += 1
return x
endfunction
let d = {'ret': function('s:Bar')}
delfunction s:Bar " <<< HERE
return d.ret
endfunction
let Count = MyPluginFoo()
echo Count() " => 1
echo Count() " => 2
echo Count() " => 3
let Count2 = MyPluginFoo()
echo Count() " => 4
echo Count() " => 5
echo Count() " => 6
echo s:Bar() " => E117: Unknown function s:Bar
I there even have an explicit test that checks that funcrefs reference
a function.
>
> Regards,
> Ken Takata
>
> --
> --
> 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.