Nikolay Pavlov wrote:

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


Yes, the old funcrefs are a bit weird.  Unfortunately we can't just
simply switch to references.  I haven't checked your patch recently, but
I was wondering if there are any backwards compatibility problems.

E.g., currently if a funcref refers to "Bar" it will find the function
by that name.  If we would instead have an actual reference, and "Bar"
gets redefined, how does it get to point to the new "Bar"?  Well, when
redefining it does re-use the function struct, thus it might just work.

The problem that brought us here is the opposite, we actually want a
reference, even when the function gets redefined.

In the Partial type instead of a function name we could use a pointer to
the function.  That saves a lookup by name at least.  Could do this
always for lambdas, perhaps also for numbered functions.  Not sure about
actual named functions.  We get the problem when "Bar" is redefined, as
mentioned above.

-- 
   [The rest of the ARMY stand around looking at a loss.]
INSPECTOR END OF FILM: (picks up megaphone) All right!  Clear off!  Go on!
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

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