[patch] Lambda with closure (Re: Got E121: Undefined variable in lambda function)

2016-07-29 Fir de Conversatie Ken Takata
Hi,

2016/7/29 Fri 20:29:33 UTC+9 Ken Takata wrote:
> > > > 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.
> 
> The patch #2 is slightly updated. Some old codes and comments were remained.
> #3 is the same as before.
> 
> 2. Lambda with capture-by-reference:
>
> https://bitbucket.org/k_takata/vim-ktakata-mq/src/ffee5ce8c564f71ddbd3b8b6abd8814583472f94/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

An additional patch for #3 is here:

4. Support unlet in closure:
   
https://bitbucket.org/k_takata/vim-ktakata-mq/src/6fd892383533a9a4499665188b413dc10fb86657/closure-unlet.patch?at=default

This enables unletting outer scope variables from a closure.  I'm not sure
how this is useful.  BTW, now all the features in mattn's lambda patch are
ported on top of the latest code base.


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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Got E121: Undefined variable in lambda function

2016-07-28 Fir de Conversatie Bram Moolenaar

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

Re: Got E121: Undefined variable in lambda function

2016-07-27 Fir de Conversatie Ken Takata
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

Re: Got E121: Undefined variable in lambda function

2016-07-25 Fir de Conversatie Ken Takata
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.)

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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Got E121: Undefined variable in lambda function

2016-07-24 Fir de Conversatie Ken Takata
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?

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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Got E121: Undefined variable in lambda function

2016-07-22 Fir de Conversatie Ken Takata
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.

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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Got E121: Undefined variable in lambda function

2016-07-22 Fir de Conversatie Nikolay Aleksandrovich Pavlov
2016-07-22 14:12 GMT+03:00 Nikolay Aleksandrovich Pavlov :
> 2016-07-22 14:09 GMT+03:00 Nikolay Aleksandrovich Pavlov :
>> 2016-07-20 21:23 GMT+03:00 Ken Takata :
>>> Hi,
>>>
>>> 2016/7/19 Tue 23:18:30 UTC+9 ZyX wrote:
 2016-07-19 17:15 GMT+03:00 Nikolay Aleksandrovich Pavlov 
 :
 > 2016-07-19 16:46 GMT+03:00 Ken Takata :
 >> Hi,
 >>
 >> 2016/7/18 Mon 11:26:23 UTC+9 Ken Takata wrote:
 >>> Hi,
 >>>
 >>> 2016/7/17 Sun 21:26:29 UTC+9 itchyny wrote:
 >>> > I additionally submit another test case.
 >>> >
 >>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> 
 >>> > x(x)(y)})}))}
 >>> > let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
 >>> > echo Y(Fact)(5)
 >>> >
 >>> > I expect this script prints 120 but I got E110: Missing ')' in 
 >>> > 7.4.2049 (and also with the experimental patch).
 >>> > Is there something wrong with the above code or is there some bug in 
 >>> > the parsing code in eval.c?
 >>> >
 >>> > Here are the counterparts in Python
 >>> > Y = lambda f: (lambda x: f (lambda y: x(x)(y))) (lambda x: f (lambda 
 >>> > y: x(x)(y)))
 >>> > Fact = lambda f: lambda x: (1 if x == 0 else x * f(x - 1))
 >>> > print Y(Fact)(5)
 >>> >
 >>> > and in JavaScript
 >>> > var Y = function(f){ return (function(x){ return f (function(y){ 
 >>> > return x(x)(y); }); }) (function(x){ return f (function(y){ return 
 >>> > x(x)(y); }); }); };
 >>> > var Fact = function(f){ return function(x){ return (x == 0 ? 1 : x * 
 >>> > f(x - 1)); }; };
 >>> > console.log(Y(Fact)(5));
 >>> >
 >>> > reference: 
 >>> > https://en.wikipedia.org/wiki/Lambda_calculus#Recursion_and_fixed_points,
 >>> >  
 >>> > https://en.wikipedia.org/wiki/Fixed-point_combinator#Fixed_point_combinators_in_lambda_calculus
 >>>
 >>> I have updated the patch for the latest code:
 >>> https://bitbucket.org/k_takata/vim-ktakata-mq/src/006cdbbeef26201154d04b7dfe1aed119321acb1/lambda-update.patch?at=default
 >>>
 >>> The SEGV on test_alot.vim seems fixed.
 >>>
 >>>
 >>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> 
 >>> > x(x)(y)})}))}
 >>>
 >>> This still causes errors. Not sure why. Simpler example would be 
 >>> better.
 >>
 >> I have updated the patch:
 >> https://bitbucket.org/k_takata/vim-ktakata-mq/src/29d0a0ecfa23f70852fa3f5c33e15ea629cd17b4/lambda-update.patch?fileviewer=file-view-default
 >
 > What happens in case of
 >
 > function Foo(arg)
 > let d = {}
 > let d.f = {-> d}
 > return d.f
 > endfunction
 > let i = 0
 > while i < 100 | call Foo() | endwhile
 >
 > ? Specifically I suspect memory leak here because lambdas now are
 > (implicit) containers, but you did not touch GC.

 Forgot `let i += 1`. Though it should still be interruptible by
 ``, so `while 1` may even be better for a quick test: if
 everything is fine, memory usage will drop after ``, but may
 increase before (AFAIR, by default full GC which checks for cycles is
 run at main loop when waiting for characters). If not, it will not.
>>>
>>> I have slightly updated the patch:
>>> https://bitbucket.org/k_takata/vim-ktakata-mq/src/162e04a587ce7e0b6b4ce46afe092cc4a5ab21e0/lambda-update.patch?fileviewer=file-view-default
>>>
>>> Some tests based on mattn's patch are added. (Not all yet.)
>>>
>>>
>>> function! Foo()
>>> let d = {}
>>> let d.f = {-> d}
>>> "let d.f = d
>>> return d.f
>>> endfunction
>>> let i = 0 | while i < 100 | call Foo() | let i+= 1 | endwhile
>>>
>>> While running this loop, memory usage increases, but it decreases after 
>>> ending
>>> the loop.  This is almost the same when the line "let d.f = d" is used 
>>> instead
>>> of the lambda expression.  However more tests might be needed to check that
>>> there is no memory leakage.
>>
>> 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:
>>
>> ```
>> #0  0x7f85da75b947 in kill () from /lib64/libc.so.6
>> #1  0x00598928 in mch_exit ()
>> #2  0x006c8f87 in getout ()
>> #3  0x0059695e in deathtrap ()
>> #4  
>> #5  0x7f85da7aa5ba in strlen () from /lib64/libc.so.6
>> #6  0x00474173 in string_quote ()
>> #7  0x004582ac in 

Re: Got E121: Undefined variable in lambda function

2016-07-22 Fir de Conversatie Nikolay Aleksandrovich Pavlov
2016-07-22 14:09 GMT+03:00 Nikolay Aleksandrovich Pavlov :
> 2016-07-20 21:23 GMT+03:00 Ken Takata :
>> Hi,
>>
>> 2016/7/19 Tue 23:18:30 UTC+9 ZyX wrote:
>>> 2016-07-19 17:15 GMT+03:00 Nikolay Aleksandrovich Pavlov 
>>> :
>>> > 2016-07-19 16:46 GMT+03:00 Ken Takata :
>>> >> Hi,
>>> >>
>>> >> 2016/7/18 Mon 11:26:23 UTC+9 Ken Takata wrote:
>>> >>> Hi,
>>> >>>
>>> >>> 2016/7/17 Sun 21:26:29 UTC+9 itchyny wrote:
>>> >>> > I additionally submit another test case.
>>> >>> >
>>> >>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> 
>>> >>> > x(x)(y)})}))}
>>> >>> > let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
>>> >>> > echo Y(Fact)(5)
>>> >>> >
>>> >>> > I expect this script prints 120 but I got E110: Missing ')' in 
>>> >>> > 7.4.2049 (and also with the experimental patch).
>>> >>> > Is there something wrong with the above code or is there some bug in 
>>> >>> > the parsing code in eval.c?
>>> >>> >
>>> >>> > Here are the counterparts in Python
>>> >>> > Y = lambda f: (lambda x: f (lambda y: x(x)(y))) (lambda x: f (lambda 
>>> >>> > y: x(x)(y)))
>>> >>> > Fact = lambda f: lambda x: (1 if x == 0 else x * f(x - 1))
>>> >>> > print Y(Fact)(5)
>>> >>> >
>>> >>> > and in JavaScript
>>> >>> > var Y = function(f){ return (function(x){ return f (function(y){ 
>>> >>> > return x(x)(y); }); }) (function(x){ return f (function(y){ return 
>>> >>> > x(x)(y); }); }); };
>>> >>> > var Fact = function(f){ return function(x){ return (x == 0 ? 1 : x * 
>>> >>> > f(x - 1)); }; };
>>> >>> > console.log(Y(Fact)(5));
>>> >>> >
>>> >>> > reference: 
>>> >>> > https://en.wikipedia.org/wiki/Lambda_calculus#Recursion_and_fixed_points,
>>> >>> >  
>>> >>> > https://en.wikipedia.org/wiki/Fixed-point_combinator#Fixed_point_combinators_in_lambda_calculus
>>> >>>
>>> >>> I have updated the patch for the latest code:
>>> >>> https://bitbucket.org/k_takata/vim-ktakata-mq/src/006cdbbeef26201154d04b7dfe1aed119321acb1/lambda-update.patch?at=default
>>> >>>
>>> >>> The SEGV on test_alot.vim seems fixed.
>>> >>>
>>> >>>
>>> >>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> 
>>> >>> > x(x)(y)})}))}
>>> >>>
>>> >>> This still causes errors. Not sure why. Simpler example would be better.
>>> >>
>>> >> I have updated the patch:
>>> >> https://bitbucket.org/k_takata/vim-ktakata-mq/src/29d0a0ecfa23f70852fa3f5c33e15ea629cd17b4/lambda-update.patch?fileviewer=file-view-default
>>> >
>>> > What happens in case of
>>> >
>>> > function Foo(arg)
>>> > let d = {}
>>> > let d.f = {-> d}
>>> > return d.f
>>> > endfunction
>>> > let i = 0
>>> > while i < 100 | call Foo() | endwhile
>>> >
>>> > ? Specifically I suspect memory leak here because lambdas now are
>>> > (implicit) containers, but you did not touch GC.
>>>
>>> Forgot `let i += 1`. Though it should still be interruptible by
>>> ``, so `while 1` may even be better for a quick test: if
>>> everything is fine, memory usage will drop after ``, but may
>>> increase before (AFAIR, by default full GC which checks for cycles is
>>> run at main loop when waiting for characters). If not, it will not.
>>
>> I have slightly updated the patch:
>> https://bitbucket.org/k_takata/vim-ktakata-mq/src/162e04a587ce7e0b6b4ce46afe092cc4a5ab21e0/lambda-update.patch?fileviewer=file-view-default
>>
>> Some tests based on mattn's patch are added. (Not all yet.)
>>
>>
>> function! Foo()
>> let d = {}
>> let d.f = {-> d}
>> "let d.f = d
>> return d.f
>> endfunction
>> let i = 0 | while i < 100 | call Foo() | let i+= 1 | endwhile
>>
>> While running this loop, memory usage increases, but it decreases after 
>> ending
>> the loop.  This is almost the same when the line "let d.f = d" is used 
>> instead
>> of the lambda expression.  However more tests might be needed to check that
>> there is no memory leakage.
>
> 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:
>
> ```
> #0  0x7f85da75b947 in kill () from /lib64/libc.so.6
> #1  0x00598928 in mch_exit ()
> #2  0x006c8f87 in getout ()
> #3  0x0059695e in deathtrap ()
> #4  
> #5  0x7f85da7aa5ba in strlen () from /lib64/libc.so.6
> #6  0x00474173 in string_quote ()
> #7  0x004582ac in dict2string ()
> #8  0x00476aa5 in echo_string_core ()
> #9  0x0047d253 in ex_echo ()
> #10 0x004c13cb in do_one_cmd ()
> #11 0x004c51fa in do_cmdline ()
> #12 0x0055f545 in 

Re: Got E121: Undefined variable in lambda function

2016-07-22 Fir de Conversatie Nikolay Aleksandrovich Pavlov
2016-07-20 21:23 GMT+03:00 Ken Takata :
> Hi,
>
> 2016/7/19 Tue 23:18:30 UTC+9 ZyX wrote:
>> 2016-07-19 17:15 GMT+03:00 Nikolay Aleksandrovich Pavlov :
>> > 2016-07-19 16:46 GMT+03:00 Ken Takata :
>> >> Hi,
>> >>
>> >> 2016/7/18 Mon 11:26:23 UTC+9 Ken Takata wrote:
>> >>> Hi,
>> >>>
>> >>> 2016/7/17 Sun 21:26:29 UTC+9 itchyny wrote:
>> >>> > I additionally submit another test case.
>> >>> >
>> >>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> 
>> >>> > x(x)(y)})}))}
>> >>> > let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
>> >>> > echo Y(Fact)(5)
>> >>> >
>> >>> > I expect this script prints 120 but I got E110: Missing ')' in 
>> >>> > 7.4.2049 (and also with the experimental patch).
>> >>> > Is there something wrong with the above code or is there some bug in 
>> >>> > the parsing code in eval.c?
>> >>> >
>> >>> > Here are the counterparts in Python
>> >>> > Y = lambda f: (lambda x: f (lambda y: x(x)(y))) (lambda x: f (lambda 
>> >>> > y: x(x)(y)))
>> >>> > Fact = lambda f: lambda x: (1 if x == 0 else x * f(x - 1))
>> >>> > print Y(Fact)(5)
>> >>> >
>> >>> > and in JavaScript
>> >>> > var Y = function(f){ return (function(x){ return f (function(y){ 
>> >>> > return x(x)(y); }); }) (function(x){ return f (function(y){ return 
>> >>> > x(x)(y); }); }); };
>> >>> > var Fact = function(f){ return function(x){ return (x == 0 ? 1 : x * 
>> >>> > f(x - 1)); }; };
>> >>> > console.log(Y(Fact)(5));
>> >>> >
>> >>> > reference: 
>> >>> > https://en.wikipedia.org/wiki/Lambda_calculus#Recursion_and_fixed_points,
>> >>> >  
>> >>> > https://en.wikipedia.org/wiki/Fixed-point_combinator#Fixed_point_combinators_in_lambda_calculus
>> >>>
>> >>> I have updated the patch for the latest code:
>> >>> https://bitbucket.org/k_takata/vim-ktakata-mq/src/006cdbbeef26201154d04b7dfe1aed119321acb1/lambda-update.patch?at=default
>> >>>
>> >>> The SEGV on test_alot.vim seems fixed.
>> >>>
>> >>>
>> >>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> 
>> >>> > x(x)(y)})}))}
>> >>>
>> >>> This still causes errors. Not sure why. Simpler example would be better.
>> >>
>> >> I have updated the patch:
>> >> https://bitbucket.org/k_takata/vim-ktakata-mq/src/29d0a0ecfa23f70852fa3f5c33e15ea629cd17b4/lambda-update.patch?fileviewer=file-view-default
>> >
>> > What happens in case of
>> >
>> > function Foo(arg)
>> > let d = {}
>> > let d.f = {-> d}
>> > return d.f
>> > endfunction
>> > let i = 0
>> > while i < 100 | call Foo() | endwhile
>> >
>> > ? Specifically I suspect memory leak here because lambdas now are
>> > (implicit) containers, but you did not touch GC.
>>
>> Forgot `let i += 1`. Though it should still be interruptible by
>> ``, so `while 1` may even be better for a quick test: if
>> everything is fine, memory usage will drop after ``, but may
>> increase before (AFAIR, by default full GC which checks for cycles is
>> run at main loop when waiting for characters). If not, it will not.
>
> I have slightly updated the patch:
> https://bitbucket.org/k_takata/vim-ktakata-mq/src/162e04a587ce7e0b6b4ce46afe092cc4a5ab21e0/lambda-update.patch?fileviewer=file-view-default
>
> Some tests based on mattn's patch are added. (Not all yet.)
>
>
> function! Foo()
> let d = {}
> let d.f = {-> d}
> "let d.f = d
> return d.f
> endfunction
> let i = 0 | while i < 100 | call Foo() | let i+= 1 | endwhile
>
> While running this loop, memory usage increases, but it decreases after ending
> the loop.  This is almost the same when the line "let d.f = d" is used instead
> of the lambda expression.  However more tests might be needed to check that
> there is no memory leakage.

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:

```
#0  0x7f85da75b947 in kill () from /lib64/libc.so.6
#1  0x00598928 in mch_exit ()
#2  0x006c8f87 in getout ()
#3  0x0059695e in deathtrap ()
#4  
#5  0x7f85da7aa5ba in strlen () from /lib64/libc.so.6
#6  0x00474173 in string_quote ()
#7  0x004582ac in dict2string ()
#8  0x00476aa5 in echo_string_core ()
#9  0x0047d253 in ex_echo ()
#10 0x004c13cb in do_one_cmd ()
#11 0x004c51fa in do_cmdline ()
#12 0x0055f545 in nv_colon ()
#13 0x0056cb48 in normal_cmd ()
#14 0x006c8b65 in main_loop ()
#15 0x0043c21c in main ()
```

When not it crashes and hangs either immediately or when I press :, if
I comment garbagecollect() call, but then 

Re: Got E121: Undefined variable in lambda function

2016-07-20 Fir de Conversatie Ken Takata
Hi,

2016/7/19 Tue 23:18:30 UTC+9 ZyX wrote:
> 2016-07-19 17:15 GMT+03:00 Nikolay Aleksandrovich Pavlov :
> > 2016-07-19 16:46 GMT+03:00 Ken Takata :
> >> Hi,
> >>
> >> 2016/7/18 Mon 11:26:23 UTC+9 Ken Takata wrote:
> >>> Hi,
> >>>
> >>> 2016/7/17 Sun 21:26:29 UTC+9 itchyny wrote:
> >>> > I additionally submit another test case.
> >>> >
> >>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
> >>> > let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
> >>> > echo Y(Fact)(5)
> >>> >
> >>> > I expect this script prints 120 but I got E110: Missing ')' in 7.4.2049 
> >>> > (and also with the experimental patch).
> >>> > Is there something wrong with the above code or is there some bug in 
> >>> > the parsing code in eval.c?
> >>> >
> >>> > Here are the counterparts in Python
> >>> > Y = lambda f: (lambda x: f (lambda y: x(x)(y))) (lambda x: f (lambda y: 
> >>> > x(x)(y)))
> >>> > Fact = lambda f: lambda x: (1 if x == 0 else x * f(x - 1))
> >>> > print Y(Fact)(5)
> >>> >
> >>> > and in JavaScript
> >>> > var Y = function(f){ return (function(x){ return f (function(y){ return 
> >>> > x(x)(y); }); }) (function(x){ return f (function(y){ return x(x)(y); 
> >>> > }); }); };
> >>> > var Fact = function(f){ return function(x){ return (x == 0 ? 1 : x * 
> >>> > f(x - 1)); }; };
> >>> > console.log(Y(Fact)(5));
> >>> >
> >>> > reference: 
> >>> > https://en.wikipedia.org/wiki/Lambda_calculus#Recursion_and_fixed_points,
> >>> >  
> >>> > https://en.wikipedia.org/wiki/Fixed-point_combinator#Fixed_point_combinators_in_lambda_calculus
> >>>
> >>> I have updated the patch for the latest code:
> >>> https://bitbucket.org/k_takata/vim-ktakata-mq/src/006cdbbeef26201154d04b7dfe1aed119321acb1/lambda-update.patch?at=default
> >>>
> >>> The SEGV on test_alot.vim seems fixed.
> >>>
> >>>
> >>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
> >>>
> >>> This still causes errors. Not sure why. Simpler example would be better.
> >>
> >> I have updated the patch:
> >> https://bitbucket.org/k_takata/vim-ktakata-mq/src/29d0a0ecfa23f70852fa3f5c33e15ea629cd17b4/lambda-update.patch?fileviewer=file-view-default
> >
> > What happens in case of
> >
> > function Foo(arg)
> > let d = {}
> > let d.f = {-> d}
> > return d.f
> > endfunction
> > let i = 0
> > while i < 100 | call Foo() | endwhile
> >
> > ? Specifically I suspect memory leak here because lambdas now are
> > (implicit) containers, but you did not touch GC.
> 
> Forgot `let i += 1`. Though it should still be interruptible by
> ``, so `while 1` may even be better for a quick test: if
> everything is fine, memory usage will drop after ``, but may
> increase before (AFAIR, by default full GC which checks for cycles is
> run at main loop when waiting for characters). If not, it will not.

I have slightly updated the patch:
https://bitbucket.org/k_takata/vim-ktakata-mq/src/162e04a587ce7e0b6b4ce46afe092cc4a5ab21e0/lambda-update.patch?fileviewer=file-view-default

Some tests based on mattn's patch are added. (Not all yet.)


function! Foo()
let d = {}
let d.f = {-> d}
"let d.f = d
return d.f
endfunction
let i = 0 | while i < 100 | call Foo() | let i+= 1 | endwhile

While running this loop, memory usage increases, but it decreases after ending
the loop.  This is almost the same when the line "let d.f = d" is used instead
of the lambda expression.  However more tests might be needed to check that
there is no memory leakage.


> > Also you should not omit using dict_alloc(). `copy_vars()` looks like
> > something that should be in dict.c. Also it looks like something that
> > is already implemented: looks much like extend(), so you probably just
> > need to employ `dict_extend()`. Probably modifying it, but I doubt

I didn't notice the function dict_extend().

> > that `copyitem = FALSE` is valid, wanting to see whether your example
> > works with `let Bar = Foo("test: using allocated string")`.

l: and a: dictionaries are handled differently in the function
call_user_func().


> > And, I guess, Bram will reject this because you copy the whole l: and
> > a: dictionaries.

Not all l: and d: dictionaries are copied. Only used variables are copied,
but they are copied twice.

1. When parsing a lambda, check all used l: and a: variables and copy them to
   dictionaries in ufunc_T structure.
2. When executing the lambda, the all l: and a: variables in ufunc_T are
   copied to l: and a: dictionaries in funccall_T structure. 

Mattn's implementation was storing only the references to l: and a: (but even
they are not used). Not sure which is better.

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 

Re: Got E121: Undefined variable in lambda function

2016-07-19 Fir de Conversatie Bram Moolenaar

Nikolay Pavlov wrote:

[...]

> >> The difference is a space between a lambda expression and its arguments.
> >> A similar example is here:
> >>
> >>let x = function('sin') (1) " E15
> >>let x = function('sin')(1)  " OK
> >>
> >> I'm not sure this is intended.
> >
> > Yes, there should not be a space between the function and the (args).
> 
> Space is OK if “function” is an identifier (variable or function
> name). E.g. `echo string (5)` displays `5`, `let String = function
> ('string') | echo String (5)` also is OK. But, I guess, fixing this
> will make some :echo calls fail.

What I mean is that one should not put a space before (args).  That
makes it easier to read, it is clear that it is a function call.

The space is allowed in some places, and that won't change because of
backwards compatibility.  But for new syntax I prefer to disallow it.

-- 
Q: Is selling software the same as selling hardware?
A: No, good hardware is sold new, good software has already been used by many.

 /// Bram Moolenaar -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Got E121: Undefined variable in lambda function

2016-07-19 Fir de Conversatie Nikolay Aleksandrovich Pavlov
2016-07-19 17:56 GMT+03:00 Bram Moolenaar :
>
> Ken Takata wrote:
>
>> 2016/7/18 Mon 11:26:23 UTC+9 Ken Takata wrote:
>> > Hi,
>> >
>> > 2016/7/17 Sun 21:26:29 UTC+9 itchyny wrote:
>> > > I additionally submit another test case.
>> > >
>> > > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
>> > > let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
>> > > echo Y(Fact)(5)
>> > >
>> > > I expect this script prints 120 but I got E110: Missing ')' in 7.4.2049 
>> > > (and also with the experimental patch).
>> > > Is there something wrong with the above code or is there some bug in the 
>> > > parsing code in eval.c?
>> > >
>> > > Here are the counterparts in Python
>> > > Y = lambda f: (lambda x: f (lambda y: x(x)(y))) (lambda x: f (lambda y: 
>> > > x(x)(y)))
>> > > Fact = lambda f: lambda x: (1 if x == 0 else x * f(x - 1))
>> > > print Y(Fact)(5)
>> > >
>> > > and in JavaScript
>> > > var Y = function(f){ return (function(x){ return f (function(y){ return 
>> > > x(x)(y); }); }) (function(x){ return f (function(y){ return x(x)(y); }); 
>> > > }); };
>> > > var Fact = function(f){ return function(x){ return (x == 0 ? 1 : x * f(x 
>> > > - 1)); }; };
>> > > console.log(Y(Fact)(5));
>> > >
>> > > reference: 
>> > > https://en.wikipedia.org/wiki/Lambda_calculus#Recursion_and_fixed_points,
>> > >  
>> > > https://en.wikipedia.org/wiki/Fixed-point_combinator#Fixed_point_combinators_in_lambda_calculus
>> >
>> > I have updated the patch for the latest code:
>> > https://bitbucket.org/k_takata/vim-ktakata-mq/src/006cdbbeef26201154d04b7dfe1aed119321acb1/lambda-update.patch?at=default
>> >
>> > The SEGV on test_alot.vim seems fixed.
>> >
>> >
>> > > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
>> >
>> > This still causes errors. Not sure why. Simpler example would be better.
>>
>> I have updated the patch:
>> https://bitbucket.org/k_takata/vim-ktakata-mq/src/29d0a0ecfa23f70852fa3f5c33e15ea629cd17b4/lambda-update.patch?fileviewer=file-view-default
>>
>> Now lambda expressions can access outer arguments. E.g.:
>>
>>   :function Foo(arg)
>>   :  return {x -> x + a:arg}
>>   :endfunction
>>   :let Bar = Foo(5)
>>   :echo Bar(2)
>>   7
>>
>> And now I disable the "a:" prefix for the lambda's arguments:
>>
>>   :function Foo(arg)
>>   :  return {x -> a:x + a:arg}  " Error
>>   :endfunction
>>
>> "a:" is now used for outer arguments only.
>>
>>
>> > > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
>> > > let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
>> > > echo Y(Fact)(5)
>>
>> The above doesn't work, but the following works now:
>>
>>:let Y = {f -> (({x -> f ({y -> x(x)(y)})})({x -> f ({y -> x(x)(y)})}))}
>>:let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
>>:echo Y(Fact)(5)
>>120
>>
>> The difference is a space between a lambda expression and its arguments.
>> A similar example is here:
>>
>>let x = function('sin') (1) " E15
>>let x = function('sin')(1)  " OK
>>
>> I'm not sure this is intended.
>
> Yes, there should not be a space between the function and the (args).

Space is OK if “function” is an identifier (variable or function
name). E.g. `echo string (5)` displays `5`, `let String = function
('string') | echo String (5)` also is OK. But, I guess, fixing this
will make some :echo calls fail.

>
>> BTW, I will update the tests later.
>
> Thanks, will look at it then.
>
> --
> [clop clop]
> MORTICIAN:  Who's that then?
> CUSTOMER:   I don't know.
> MORTICIAN:  Must be a king.
> CUSTOMER:   Why?
> MORTICIAN:  He hasn't got shit all over him.
>   The Quest for the Holy Grail (Monty Python)
>
>  /// Bram Moolenaar -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
> 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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit 

Re: Got E121: Undefined variable in lambda function

2016-07-19 Fir de Conversatie Bram Moolenaar

Ken Takata wrote:

> 2016/7/18 Mon 11:26:23 UTC+9 Ken Takata wrote:
> > Hi,
> > 
> > 2016/7/17 Sun 21:26:29 UTC+9 itchyny wrote:
> > > I additionally submit another test case.
> > > 
> > > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
> > > let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
> > > echo Y(Fact)(5)
> > > 
> > > I expect this script prints 120 but I got E110: Missing ')' in 7.4.2049 
> > > (and also with the experimental patch).
> > > Is there something wrong with the above code or is there some bug in the 
> > > parsing code in eval.c?
> > > 
> > > Here are the counterparts in Python
> > > Y = lambda f: (lambda x: f (lambda y: x(x)(y))) (lambda x: f (lambda y: 
> > > x(x)(y)))
> > > Fact = lambda f: lambda x: (1 if x == 0 else x * f(x - 1))
> > > print Y(Fact)(5)
> > > 
> > > and in JavaScript
> > > var Y = function(f){ return (function(x){ return f (function(y){ return 
> > > x(x)(y); }); }) (function(x){ return f (function(y){ return x(x)(y); }); 
> > > }); };
> > > var Fact = function(f){ return function(x){ return (x == 0 ? 1 : x * f(x 
> > > - 1)); }; };
> > > console.log(Y(Fact)(5));
> > > 
> > > reference: 
> > > https://en.wikipedia.org/wiki/Lambda_calculus#Recursion_and_fixed_points, 
> > > https://en.wikipedia.org/wiki/Fixed-point_combinator#Fixed_point_combinators_in_lambda_calculus
> > 
> > I have updated the patch for the latest code:
> > https://bitbucket.org/k_takata/vim-ktakata-mq/src/006cdbbeef26201154d04b7dfe1aed119321acb1/lambda-update.patch?at=default
> > 
> > The SEGV on test_alot.vim seems fixed.
> > 
> > 
> > > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
> > 
> > This still causes errors. Not sure why. Simpler example would be better.
> 
> I have updated the patch:
> https://bitbucket.org/k_takata/vim-ktakata-mq/src/29d0a0ecfa23f70852fa3f5c33e15ea629cd17b4/lambda-update.patch?fileviewer=file-view-default
> 
> Now lambda expressions can access outer arguments. E.g.:
> 
>   :function Foo(arg)
>   :  return {x -> x + a:arg}
>   :endfunction
>   :let Bar = Foo(5)
>   :echo Bar(2)
>   7
> 
> And now I disable the "a:" prefix for the lambda's arguments:
> 
>   :function Foo(arg)
>   :  return {x -> a:x + a:arg}  " Error
>   :endfunction
> 
> "a:" is now used for outer arguments only.
> 
> 
> > > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
> > > let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
> > > echo Y(Fact)(5)
> 
> The above doesn't work, but the following works now:
> 
>:let Y = {f -> (({x -> f ({y -> x(x)(y)})})({x -> f ({y -> x(x)(y)})}))}
>:let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
>:echo Y(Fact)(5)
>120
> 
> The difference is a space between a lambda expression and its arguments.
> A similar example is here:
> 
>let x = function('sin') (1) " E15
>let x = function('sin')(1)  " OK
> 
> I'm not sure this is intended.

Yes, there should not be a space between the function and the (args).

> BTW, I will update the tests later.

Thanks, will look at it then.

-- 
[clop clop]
MORTICIAN:  Who's that then?
CUSTOMER:   I don't know.
MORTICIAN:  Must be a king.
CUSTOMER:   Why?
MORTICIAN:  He hasn't got shit all over him.
  The Quest for the Holy Grail (Monty Python)

 /// Bram Moolenaar -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Got E121: Undefined variable in lambda function

2016-07-19 Fir de Conversatie Nikolay Aleksandrovich Pavlov
2016-07-19 17:15 GMT+03:00 Nikolay Aleksandrovich Pavlov :
> 2016-07-19 16:46 GMT+03:00 Ken Takata :
>> Hi,
>>
>> 2016/7/18 Mon 11:26:23 UTC+9 Ken Takata wrote:
>>> Hi,
>>>
>>> 2016/7/17 Sun 21:26:29 UTC+9 itchyny wrote:
>>> > I additionally submit another test case.
>>> >
>>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
>>> > let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
>>> > echo Y(Fact)(5)
>>> >
>>> > I expect this script prints 120 but I got E110: Missing ')' in 7.4.2049 
>>> > (and also with the experimental patch).
>>> > Is there something wrong with the above code or is there some bug in the 
>>> > parsing code in eval.c?
>>> >
>>> > Here are the counterparts in Python
>>> > Y = lambda f: (lambda x: f (lambda y: x(x)(y))) (lambda x: f (lambda y: 
>>> > x(x)(y)))
>>> > Fact = lambda f: lambda x: (1 if x == 0 else x * f(x - 1))
>>> > print Y(Fact)(5)
>>> >
>>> > and in JavaScript
>>> > var Y = function(f){ return (function(x){ return f (function(y){ return 
>>> > x(x)(y); }); }) (function(x){ return f (function(y){ return x(x)(y); }); 
>>> > }); };
>>> > var Fact = function(f){ return function(x){ return (x == 0 ? 1 : x * f(x 
>>> > - 1)); }; };
>>> > console.log(Y(Fact)(5));
>>> >
>>> > reference: 
>>> > https://en.wikipedia.org/wiki/Lambda_calculus#Recursion_and_fixed_points, 
>>> > https://en.wikipedia.org/wiki/Fixed-point_combinator#Fixed_point_combinators_in_lambda_calculus
>>>
>>> I have updated the patch for the latest code:
>>> https://bitbucket.org/k_takata/vim-ktakata-mq/src/006cdbbeef26201154d04b7dfe1aed119321acb1/lambda-update.patch?at=default
>>>
>>> The SEGV on test_alot.vim seems fixed.
>>>
>>>
>>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
>>>
>>> This still causes errors. Not sure why. Simpler example would be better.
>>
>> I have updated the patch:
>> https://bitbucket.org/k_takata/vim-ktakata-mq/src/29d0a0ecfa23f70852fa3f5c33e15ea629cd17b4/lambda-update.patch?fileviewer=file-view-default
>
> What happens in case of
>
> function Foo(arg)
> let d = {}
> let d.f = {-> d}
> return d.f
> endfunction
> let i = 0
> while i < 100 | call Foo() | endwhile
>
> ? Specifically I suspect memory leak here because lambdas now are
> (implicit) containers, but you did not touch GC.

Forgot `let i += 1`. Though it should still be interruptible by
``, so `while 1` may even be better for a quick test: if
everything is fine, memory usage will drop after ``, but may
increase before (AFAIR, by default full GC which checks for cycles is
run at main loop when waiting for characters). If not, it will not.

>
> Also you should not omit using dict_alloc(). `copy_vars()` looks like
> something that should be in dict.c. Also it looks like something that
> is already implemented: looks much like extend(), so you probably just
> need to employ `dict_extend()`. Probably modifying it, but I doubt
> that `copyitem = FALSE` is valid, wanting to see whether your example
> works with `let Bar = Foo("test: using allocated string")`.
>
> And, I guess, Bram will reject this because you copy the whole l: and
> a: dictionaries.
>
>>
>> Now lambda expressions can access outer arguments. E.g.:
>>
>> :function Foo(arg)
>> :  return {x -> x + a:arg}
>> :endfunction
>> :let Bar = Foo(5)
>> :echo Bar(2)
>> 7
>>
>> And now I disable the "a:" prefix for the lambda's arguments:
>>
>> :function Foo(arg)
>> :  return {x -> a:x + a:arg}  " Error
>> :endfunction
>>
>> "a:" is now used for outer arguments only.
>>
>>
>>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
>>> > let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
>>> > echo Y(Fact)(5)
>>
>> The above doesn't work, but the following works now:
>>
>>:let Y = {f -> (({x -> f ({y -> x(x)(y)})})({x -> f ({y -> x(x)(y)})}))}
>>:let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
>>:echo Y(Fact)(5)
>>120
>>
>> The difference is a space between a lambda expression and its arguments.
>> A similar example is here:
>>
>>let x = function('sin') (1) " E15
>>let x = function('sin')(1)  " OK
>>
>> I'm not sure this is intended.
>> BTW, I will update the tests later.
>>
>> 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 vim_dev+unsubscr...@googlegroups.com.
>> 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 

Re: Got E121: Undefined variable in lambda function

2016-07-19 Fir de Conversatie Nikolay Aleksandrovich Pavlov
2016-07-19 16:46 GMT+03:00 Ken Takata :
> Hi,
>
> 2016/7/18 Mon 11:26:23 UTC+9 Ken Takata wrote:
>> Hi,
>>
>> 2016/7/17 Sun 21:26:29 UTC+9 itchyny wrote:
>> > I additionally submit another test case.
>> >
>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
>> > let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
>> > echo Y(Fact)(5)
>> >
>> > I expect this script prints 120 but I got E110: Missing ')' in 7.4.2049 
>> > (and also with the experimental patch).
>> > Is there something wrong with the above code or is there some bug in the 
>> > parsing code in eval.c?
>> >
>> > Here are the counterparts in Python
>> > Y = lambda f: (lambda x: f (lambda y: x(x)(y))) (lambda x: f (lambda y: 
>> > x(x)(y)))
>> > Fact = lambda f: lambda x: (1 if x == 0 else x * f(x - 1))
>> > print Y(Fact)(5)
>> >
>> > and in JavaScript
>> > var Y = function(f){ return (function(x){ return f (function(y){ return 
>> > x(x)(y); }); }) (function(x){ return f (function(y){ return x(x)(y); }); 
>> > }); };
>> > var Fact = function(f){ return function(x){ return (x == 0 ? 1 : x * f(x - 
>> > 1)); }; };
>> > console.log(Y(Fact)(5));
>> >
>> > reference: 
>> > https://en.wikipedia.org/wiki/Lambda_calculus#Recursion_and_fixed_points, 
>> > https://en.wikipedia.org/wiki/Fixed-point_combinator#Fixed_point_combinators_in_lambda_calculus
>>
>> I have updated the patch for the latest code:
>> https://bitbucket.org/k_takata/vim-ktakata-mq/src/006cdbbeef26201154d04b7dfe1aed119321acb1/lambda-update.patch?at=default
>>
>> The SEGV on test_alot.vim seems fixed.
>>
>>
>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
>>
>> This still causes errors. Not sure why. Simpler example would be better.
>
> I have updated the patch:
> https://bitbucket.org/k_takata/vim-ktakata-mq/src/29d0a0ecfa23f70852fa3f5c33e15ea629cd17b4/lambda-update.patch?fileviewer=file-view-default

What happens in case of

function Foo(arg)
let d = {}
let d.f = {-> d}
return d.f
endfunction
let i = 0
while i < 100 | call Foo() | endwhile

? Specifically I suspect memory leak here because lambdas now are
(implicit) containers, but you did not touch GC.

Also you should not omit using dict_alloc(). `copy_vars()` looks like
something that should be in dict.c. Also it looks like something that
is already implemented: looks much like extend(), so you probably just
need to employ `dict_extend()`. Probably modifying it, but I doubt
that `copyitem = FALSE` is valid, wanting to see whether your example
works with `let Bar = Foo("test: using allocated string")`.

And, I guess, Bram will reject this because you copy the whole l: and
a: dictionaries.

>
> Now lambda expressions can access outer arguments. E.g.:
>
> :function Foo(arg)
> :  return {x -> x + a:arg}
> :endfunction
> :let Bar = Foo(5)
> :echo Bar(2)
> 7
>
> And now I disable the "a:" prefix for the lambda's arguments:
>
> :function Foo(arg)
> :  return {x -> a:x + a:arg}  " Error
> :endfunction
>
> "a:" is now used for outer arguments only.
>
>
>> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
>> > let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
>> > echo Y(Fact)(5)
>
> The above doesn't work, but the following works now:
>
>:let Y = {f -> (({x -> f ({y -> x(x)(y)})})({x -> f ({y -> x(x)(y)})}))}
>:let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
>:echo Y(Fact)(5)
>120
>
> The difference is a space between a lambda expression and its arguments.
> A similar example is here:
>
>let x = function('sin') (1) " E15
>let x = function('sin')(1)  " OK
>
> I'm not sure this is intended.
> BTW, I will update the tests later.
>
> 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 vim_dev+unsubscr...@googlegroups.com.
> 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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Got E121: Undefined variable in lambda function

2016-07-19 Fir de Conversatie Ken Takata
Hi,

2016/7/18 Mon 11:26:23 UTC+9 Ken Takata wrote:
> Hi,
> 
> 2016/7/17 Sun 21:26:29 UTC+9 itchyny wrote:
> > I additionally submit another test case.
> > 
> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
> > let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
> > echo Y(Fact)(5)
> > 
> > I expect this script prints 120 but I got E110: Missing ')' in 7.4.2049 
> > (and also with the experimental patch).
> > Is there something wrong with the above code or is there some bug in the 
> > parsing code in eval.c?
> > 
> > Here are the counterparts in Python
> > Y = lambda f: (lambda x: f (lambda y: x(x)(y))) (lambda x: f (lambda y: 
> > x(x)(y)))
> > Fact = lambda f: lambda x: (1 if x == 0 else x * f(x - 1))
> > print Y(Fact)(5)
> > 
> > and in JavaScript
> > var Y = function(f){ return (function(x){ return f (function(y){ return 
> > x(x)(y); }); }) (function(x){ return f (function(y){ return x(x)(y); }); 
> > }); };
> > var Fact = function(f){ return function(x){ return (x == 0 ? 1 : x * f(x - 
> > 1)); }; };
> > console.log(Y(Fact)(5));
> > 
> > reference: 
> > https://en.wikipedia.org/wiki/Lambda_calculus#Recursion_and_fixed_points, 
> > https://en.wikipedia.org/wiki/Fixed-point_combinator#Fixed_point_combinators_in_lambda_calculus
> 
> I have updated the patch for the latest code:
> https://bitbucket.org/k_takata/vim-ktakata-mq/src/006cdbbeef26201154d04b7dfe1aed119321acb1/lambda-update.patch?at=default
> 
> The SEGV on test_alot.vim seems fixed.
> 
> 
> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
> 
> This still causes errors. Not sure why. Simpler example would be better.

I have updated the patch:
https://bitbucket.org/k_takata/vim-ktakata-mq/src/29d0a0ecfa23f70852fa3f5c33e15ea629cd17b4/lambda-update.patch?fileviewer=file-view-default

Now lambda expressions can access outer arguments. E.g.:

:function Foo(arg)
:  return {x -> x + a:arg}
:endfunction
:let Bar = Foo(5)
:echo Bar(2)
7

And now I disable the "a:" prefix for the lambda's arguments:

:function Foo(arg)
:  return {x -> a:x + a:arg}  " Error
:endfunction

"a:" is now used for outer arguments only.


> > let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
> > let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
> > echo Y(Fact)(5)

The above doesn't work, but the following works now:

   :let Y = {f -> (({x -> f ({y -> x(x)(y)})})({x -> f ({y -> x(x)(y)})}))}
   :let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
   :echo Y(Fact)(5)
   120

The difference is a space between a lambda expression and its arguments.
A similar example is here:

   let x = function('sin') (1) " E15
   let x = function('sin')(1)  " OK

I'm not sure this is intended.
BTW, I will update the tests later.

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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Got E121: Undefined variable in lambda function

2016-07-17 Fir de Conversatie Ken Takata
Hi,

2016/7/17 Sun 21:26:29 UTC+9 itchyny wrote:
> I additionally submit another test case.
> 
> let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}
> let Fact = {f -> {x -> (x == 0 ? 1 : x * f(x - 1))}}
> echo Y(Fact)(5)
> 
> I expect this script prints 120 but I got E110: Missing ')' in 7.4.2049 (and 
> also with the experimental patch).
> Is there something wrong with the above code or is there some bug in the 
> parsing code in eval.c?
> 
> Here are the counterparts in Python
> Y = lambda f: (lambda x: f (lambda y: x(x)(y))) (lambda x: f (lambda y: 
> x(x)(y)))
> Fact = lambda f: lambda x: (1 if x == 0 else x * f(x - 1))
> print Y(Fact)(5)
> 
> and in JavaScript
> var Y = function(f){ return (function(x){ return f (function(y){ return 
> x(x)(y); }); }) (function(x){ return f (function(y){ return x(x)(y); }); }); 
> };
> var Fact = function(f){ return function(x){ return (x == 0 ? 1 : x * f(x - 
> 1)); }; };
> console.log(Y(Fact)(5));
> 
> reference: 
> https://en.wikipedia.org/wiki/Lambda_calculus#Recursion_and_fixed_points, 
> https://en.wikipedia.org/wiki/Fixed-point_combinator#Fixed_point_combinators_in_lambda_calculus

I have updated the patch for the latest code:
https://bitbucket.org/k_takata/vim-ktakata-mq/src/006cdbbeef26201154d04b7dfe1aed119321acb1/lambda-update.patch?at=default

The SEGV on test_alot.vim seems fixed.


> let Y = {f -> (({x -> f ({y -> x(x)(y)})}) ({x -> f ({y -> x(x)(y)})}))}

This still causes errors. Not sure why. Simpler example would be better.


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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Got E121: Undefined variable in lambda function

2016-07-17 Fir de Conversatie Ken Takata
Hi,

2016/7/17 Sun 19:37:09 UTC+9 Ken Takata wrote:
> Hi itchyny,
> 
> 2016/7/17 Sun 10:08:02 UTC+9 itchyny wrote:
> > On Sunday, July 17, 2016 at 2:56:44 AM UTC+9, Bram Moolenaar wrote:
> > > Ken Hamada wrote:
> > > 
> > > > Hi Bram and Ken Takata.
> > > > 
> > > > I think there is some problem in variable substitution of lambda 
> > > > function.
> > > > 
> > > > echo ({y -> ({x -> x(y)(10)})({y -> y})})({z -> z})
> > > > 
> > > > yields an error `E121: Undefined variable: y`. I expect this expression 
> > > > yields 10. I tested on Vim 7.4.2048.
> > > > 
> > > > JavaScript:
> > > > (function(y){ return (function(x){ return x(y)(10); })(function(y){ 
> > > > return y; }); })(function(z){ return z; })
> > > > 
> > > > Python:
> > > > (lambda y: (lambda x: x(y)(10))(lambda y: y))(lambda z: z)
> > > > 
> > > > Ruby:
> > > > (lambda {|y| (lambda {|x| (x.call(y)).call(10)}).call(lambda {|y| 
> > > > y})}).call(lambda {|z| z})
> > > > 
> > > > All these expressions prints 10 as expected.
> > > 
> > > This is because Vim does not support a closure yet.  You are using this
> > > lambda:
> > >   {x -> x(y)(10)}
> > > You can see that "y" is not defined here.  It would come from the
> > > context, but that isn't supported.
> > > 
> > 
> > I see. Thanks for explanation.
> 
> Could you try this experimental patch?
> https://bitbucket.org/k_takata/vim-ktakata-mq/src/962046ccfd7221dbb0bc29ed33e6c3d2a210e1be/lambda-update.patch?fileviewer=file-view-default
> 
> Sorry, tests are not included yet.

Hmm, it seems it has some problems. SEGV occurs with test_alot.vim.

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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Got E121: Undefined variable in lambda function

2016-07-17 Fir de Conversatie Ken Takata
Hi itchyny,

2016/7/17 Sun 10:08:02 UTC+9 itchyny wrote:
> On Sunday, July 17, 2016 at 2:56:44 AM UTC+9, Bram Moolenaar wrote:
> > Ken Hamada wrote:
> > 
> > > Hi Bram and Ken Takata.
> > > 
> > > I think there is some problem in variable substitution of lambda function.
> > > 
> > > echo ({y -> ({x -> x(y)(10)})({y -> y})})({z -> z})
> > > 
> > > yields an error `E121: Undefined variable: y`. I expect this expression 
> > > yields 10. I tested on Vim 7.4.2048.
> > > 
> > > JavaScript:
> > > (function(y){ return (function(x){ return x(y)(10); })(function(y){ 
> > > return y; }); })(function(z){ return z; })
> > > 
> > > Python:
> > > (lambda y: (lambda x: x(y)(10))(lambda y: y))(lambda z: z)
> > > 
> > > Ruby:
> > > (lambda {|y| (lambda {|x| (x.call(y)).call(10)}).call(lambda {|y| 
> > > y})}).call(lambda {|z| z})
> > > 
> > > All these expressions prints 10 as expected.
> > 
> > This is because Vim does not support a closure yet.  You are using this
> > lambda:
> > {x -> x(y)(10)}
> > You can see that "y" is not defined here.  It would come from the
> > context, but that isn't supported.
> > 
> 
> I see. Thanks for explanation.

Could you try this experimental patch?
https://bitbucket.org/k_takata/vim-ktakata-mq/src/962046ccfd7221dbb0bc29ed33e6c3d2a210e1be/lambda-update.patch?fileviewer=file-view-default

Sorry, tests are not included yet.

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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Got E121: Undefined variable in lambda function

2016-07-16 Fir de Conversatie itchyny
On Sunday, July 17, 2016 at 2:56:44 AM UTC+9, Bram Moolenaar wrote:
> Ken Hamada wrote:
> 
> > Hi Bram and Ken Takata.
> > 
> > I think there is some problem in variable substitution of lambda function.
> > 
> > echo ({y -> ({x -> x(y)(10)})({y -> y})})({z -> z})
> > 
> > yields an error `E121: Undefined variable: y`. I expect this expression 
> > yields 10. I tested on Vim 7.4.2048.
> > 
> > JavaScript:
> > (function(y){ return (function(x){ return x(y)(10); })(function(y){ return 
> > y; }); })(function(z){ return z; })
> > 
> > Python:
> > (lambda y: (lambda x: x(y)(10))(lambda y: y))(lambda z: z)
> > 
> > Ruby:
> > (lambda {|y| (lambda {|x| (x.call(y)).call(10)}).call(lambda {|y| 
> > y})}).call(lambda {|z| z})
> > 
> > All these expressions prints 10 as expected.
> 
> This is because Vim does not support a closure yet.  You are using this
> lambda:
>   {x -> x(y)(10)}
> You can see that "y" is not defined here.  It would come from the
> context, but that isn't supported.
> 

I see. Thanks for explanation.

Regards,
Ken Hamada

-- 
-- 
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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Got E121: Undefined variable in lambda function

2016-07-16 Fir de Conversatie Bram Moolenaar

Ken Hamada wrote:

> Hi Bram and Ken Takata.
> 
> I think there is some problem in variable substitution of lambda function.
> 
> echo ({y -> ({x -> x(y)(10)})({y -> y})})({z -> z})
> 
> yields an error `E121: Undefined variable: y`. I expect this expression 
> yields 10. I tested on Vim 7.4.2048.
> 
> JavaScript:
> (function(y){ return (function(x){ return x(y)(10); })(function(y){ return y; 
> }); })(function(z){ return z; })
> 
> Python:
> (lambda y: (lambda x: x(y)(10))(lambda y: y))(lambda z: z)
> 
> Ruby:
> (lambda {|y| (lambda {|x| (x.call(y)).call(10)}).call(lambda {|y| 
> y})}).call(lambda {|z| z})
> 
> All these expressions prints 10 as expected.

This is because Vim does not support a closure yet.  You are using this
lambda:
{x -> x(y)(10)}
You can see that "y" is not defined here.  It would come from the
context, but that isn't supported.

> Anyway, 7.4.2044 is surely a great advance in the history of Vim
> script. Thanks.

Glad you like it.

-- 
Luxury. We used to have to get out of the lake at three o'clock in the 
morning, clean the lake, eat a handful of hot gravel, go to work at the 
mill every day for tuppence a month, come home, and Dad would beat us 
around the head and neck with a broken bottle, if we were LUCKY!

 /// Bram Moolenaar -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Got E121: Undefined variable in lambda function

2016-07-16 Fir de Conversatie itchyny
Hi Bram and Ken Takata.

I think there is some problem in variable substitution of lambda function.

echo ({y -> ({x -> x(y)(10)})({y -> y})})({z -> z})

yields an error `E121: Undefined variable: y`. I expect this expression yields 
10. I tested on Vim 7.4.2048.

JavaScript:
(function(y){ return (function(x){ return x(y)(10); })(function(y){ return y; 
}); })(function(z){ return z; })

Python:
(lambda y: (lambda x: x(y)(10))(lambda y: y))(lambda z: z)

Ruby:
(lambda {|y| (lambda {|x| (x.call(y)).call(10)}).call(lambda {|y| 
y})}).call(lambda {|z| z})

All these expressions prints 10 as expected.

Anyway, 7.4.2044 is surely a great advance in the history of Vim script. Thanks.

Sincerely,
Ken Hamada

-- 
-- 
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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.