Ken Takata wrote:
> 2016/7/28 Thu 7:06:31 UTC+9 Ken Takata wrote:
> > Hi,
> >
> > 2016/7/28 Thu 0:57:53 UTC+9 Bram Moolenaar wrote:
> > > Ken Takata wrote:
> > >
> > > > 2016/7/25 Mon 23:02:25 UTC+9 Ken Takata wrote:
> > > > > Hi,
> > > > >
> > > > > 2016/7/25 Mon 3:47:51 UTC+9 Ken Takata wrote:
> > > > > > Hi,
> > > > > >
> > > > > > 2016/7/22 Fri 22:29:33 UTC+9 Ken Takata wrote:
> > > > > > > Hi ZyX,
> > > > > > >
> > > > > > > 2016/7/22 Fri 20:15:33 UTC+9 ZyX wrote:
> > > > > > > > >> I was wrong regarding the consequences and why you should
> > > > > > > > >> alter the
> > > > > > > > >> GC: it is not memory leak because cycle is not GC’d. It is
> > > > > > > > >> *crash*
> > > > > > > > >> because Vim does not know that dictionary is referenced:
> > > > > > > > >>
> > > > > > > > >> ```VimL
> > > > > > > > >> function F()
> > > > > > > > >> let d = {}
> > > > > > > > >> return {-> d}
> > > > > > > > >> endfunction
> > > > > > > > >> let L = F()
> > > > > > > > >> call garbagecollect(1)
> > > > > > > > >> call feedkeys(":echo L()\n", 'n')
> > > > > > > > >> ```
> > > > > > > > >>
> > > > > > > > >> Save to `test.vim` and run as `vim -u NONE -i NONE -N -S
> > > > > > > > >> test.vim`.
> > > > > > > > >> When I use it in Vim with optimizations it crashes
> > > > > > > > >> immediately:
> > > > > > >
> > > > > > > Yes, I also noticed this. I tested with the following script:
> > > > > > >
> > > > > > > function! Test_lambda_closure()
> > > > > > > function! s:foo()
> > > > > > > let x = [0]
> > > > > > > return {-> [execute("let x[0] += 1"), x[0]][-1]}
> > > > > > > endfunction
> > > > > > >
> > > > > > > let l:F = s:foo()
> > > > > > > call test_garbagecollect_now()
> > > > > > > call assert_equal(1, l:F())
> > > > > > > call assert_equal(2, l:F())
> > > > > > > call assert_equal(3, l:F())
> > > > > > > call assert_equal(4, l:F())
> > > > > > > endfunction
> > > > > > >
> > > > > > > I have updated the patch:
> > > > > > > https://bitbucket.org/k_takata/vim-ktakata-mq/src/52c8d4fd0af2dd8bd2c79204dbbedd9ded874439/lambda-update.patch?at=default
> > > > > > >
> > > > > > > Now it deals with GC. Also add some tests, reduce memory when
> > > > > > > local variables
> > > > > > > or arguments are not used.
> > > > > >
> > > > > > I have slightly updated the tests:
> > > > > > https://bitbucket.org/k_takata/vim-ktakata-mq/src/5f8f4f212a09b1fa58a939f34559c7b3c88bb616/lambda-update.patch?at=default
> > > > > >
> > > > > > It seems work well. BTW, I'm thinking the implementation again.
> > > > > > I thought that capture by value is easier to implement, but it is
> > > > > > harder to
> > > > > > apply to normal functions inside a function. Capture by reference
> > > > > > seems easier
> > > > > > to apply to normal functions.
> > > > > >
> > > > > > I read the comment for mattn's implementation by Bram again:
> > > > > >
> > > > > > > In the implementation it seems the dictionary storing the
> > > > > > > function-local
> > > > > > > variables is kept for a very long time. This relies on the garbage
> > > > > > > collector. It's better to use reference counting to be able to
> > > > > > > free the
> > > > > > > dictionary as soon as it's unused.
> > > > > > >
> > > > > > > Also, the lambda always keeps the function-local variable dict,
> > > > > > > even
> > > > > > > when it's not actually used. That makes lambdas a expensive.
> > > > > > > It would be better to explicitly state the lambda is using its
> > > > > > > context.
> > > > > > > Then we can also do that with ":function", so that we are not
> > > > > > > forced to
> > > > > > > use a lambda if we want a closure.
> > > > > >
> > > > > > Checking if a lambda is a closure is now available with my patch.
> > > > > > So I tried to implement reference counting based on mattn's patch.
> > > > > > Unfortunately it doesn't work well yet. I need help for this.
> > > > > > https://bitbucket.org/k_takata/vim-ktakata-mq/src/5f8f4f212a09b1fa58a939f34559c7b3c88bb616/lambda-capture_by_reference-temp.patch?at=default
> > > > > > (This patch should be applied after the above patch
> > > > > > (lambda-update.patch).)
> > > > > > Test_circular_reference() in test_lambda.vim doesn't work well.
> > > > > >
> > > > > > Which is better, capture by value or by reference?
> > > > >
> > > > > I have updated the patches.
> > > > >
> > > > > Capture by value:
> > > > > https://bitbucket.org/k_takata/vim-ktakata-mq/src/05cb2721d17d4b1c52b603037e3ec65e523b472d/lambda-update.patch?at=default
> > > > >
> > > > > Capture by reference:
> > > > > https://bitbucket.org/k_takata/vim-ktakata-mq/src/05cb2721d17d4b1c52b603037e3ec65e523b472d/lambda-capture_by_reference.patch?at=default
> > > > > (Apply on top of lambda-update.patch)
> > > > >
> > > > > Now both seem to work almost good.
> > > > > And I wrote another patch to support closure with normal functions:
> > > > > https://bitbucket.org/k_takata/vim-ktakata-mq/src/cf0cce51b390335d5ed5a5dffa933e10f16d3aab/closure.patch?at=default
> > > > > (Apply on top of lambda-capture_by_reference.patch)
> > > > >
> > > > > The :function command supports [closure] argument now:
> > > > >
> > > > > function! Foo()
> > > > > let x = 0
> > > > > function! Bar() closure
> > > > > let x += 1
> > > > > return x
> > > > > endfunction
> > > > > return function('Bar')
> > > > > endfunction
> > > > >
> > > > > let F = Foo()
> > > > > echo F() " 1
> > > > > echo F() " 2
> > > > > echo F() " 3
> > > > > echo F() " 4
> > > > >
> > > > > (Documents and tests are not updated yet.)
> > > >
> > > > Lambda and closure patches are updated:
> > > >
> > > > *
> > > > https://bitbucket.org/k_takata/vim-ktakata-mq/src/0d62ba414841e96e1a7778bb92155d17315ee3d5/lambda-update.patch?at=default
> > > > *
> > > > https://bitbucket.org/k_takata/vim-ktakata-mq/src/0d62ba414841e96e1a7778bb92155d17315ee3d5/lambda-capture_by_reference.patch?at=default
> > > > *
> > > > https://bitbucket.org/k_takata/vim-ktakata-mq/src/0d62ba414841e96e1a7778bb92155d17315ee3d5/closure.patch?at=default
> > > >
> > > > Some tests are added and documents are updated.
> > >
> > > I'm getting a bit confused. Are these two alternatives that we need to
> > > decide which one will be included? And the third one goes on top of
> > > either of them?
> >
> > Sorry, that was confusing. I rearranged the patches:
> >
> > 1. Lambda with capture-by-value:
> >
> > https://bitbucket.org/k_takata/vim-ktakata-mq/src/9a62b8ce9304e1c0f78c70d524c1d8d8a8015cc7/lambda-capture_by_value.patch?at=default
> >
> > 2. Lambda with capture-by-reference:
> >
> > https://bitbucket.org/k_takata/vim-ktakata-mq/src/9a62b8ce9304e1c0f78c70d524c1d8d8a8015cc7/lambda-capture_by_reference.patch?at=default
> >
> > 3. Closure with normal functions:
> >
> > https://bitbucket.org/k_takata/vim-ktakata-mq/src/9a62b8ce9304e1c0f78c70d524c1d8d8a8015cc7/closure.patch?at=default
> >
> > #1 and #2 are exclusive. We need to decide which one will be included, but
> > now I think #1 has no merits.
> > #3 needs to be applied on top of #2.
>
> The patches #2 and #3 are updated:
>
> 2. Lambda with capture-by-reference:
>
> https://bitbucket.org/k_takata/vim-ktakata-mq/src/d6b0edc0785baa51bead7f00271fb7bec484f69e/lambda-capture_by_reference.patch?at=default
>
> 3. Closure with normal functions:
>
> https://bitbucket.org/k_takata/vim-ktakata-mq/src/d6b0edc0785baa51bead7f00271fb7bec484f69e/closure.patch?at=default
>
> Fixed memory leaks and double free problems.
> Now all tests pass.
Thanks. I'll have a look and when it looks good I'll include it.
--
There is no right or wrong, there is only your personal opinion.
(Bram Moolenaar)
/// 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.