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.

Raspunde prin e-mail lui