Ken Takata wrote:
> 2016/7/31 Sun 4:17:46 UTC+9 Bram Moolenaar wrote:
> > 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)
>
> I found another problem. The following causes an error:
>
> function! Foo()
> let x = 0
> function! Bar() closure
> let x += 1
> return x
> endfunction
> return function('Bar')
> endfunction
>
> let Count = Foo()
> call test_garbagecollect_now()
> echo Count() " Cannot access x
>
> Reference counting was wrong. The following patch fixes the problem:
> https://bitbucket.org/k_takata/vim-ktakata-mq/src/7685fd93bf6a1ea0079d7c7da537dc062a67bc9f/fix-closure-refcount.patch?at=default
I had trouble reproducing this problem. Looks like Foo() needs to be
called twice. But then your patch doesn't fix it...
While trying to write a test I also noticed memory access errors when
using :delfunction.
> > 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.
>
> Hmm, do you say that this is expected behavior?
>
> I think Bar() should be an unnamed function like a lambda, and it should not
> overwrite existing Bar(). Bar() should be a local function inside Foo().
Hmm, thus adding "closure" changes how the function is defined? I don't
think that is a good idea. It is not what one expects. If we want
local-scope functions I don't think that adding "closure" is the way to
do that.
> I wrote a patch to fix this:
> https://bitbucket.org/k_takata/vim-ktakata-mq/src/7685fd93bf6a1ea0079d7c7da537dc062a67bc9f/fix-closure.patch?at=default
>
> Please apply the following patch before the above patch:
> https://groups.google.com/d/msg/vim_dev/xSCXQ0cmnzo/UUfR81o0BgAJ
>
> fix-closure-refcount.patch is also needed.
>
> With these patches, "function! Bar() closure" creates an unnamed function
> (internal name: "<closure>N"), and set the Funcref to a local variable "Bar".
> This is a little bit tricky by the counter example works fine.
> What do you think?
I'll have a closer look at the code.
--
"I love deadlines. I especially like the whooshing sound they
make as they go flying by."
-- Douglas Adams
/// 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.