Hi,

2016/7/19 Tue 23:18:30 UTC+9 ZyX wrote:
> 2016-07-19 17:15 GMT+03:00 Nikolay Aleksandrovich Pavlov <zyx....@gmail.com>:
> > 2016-07-19 16:46 GMT+03:00 Ken Takata <ktakata65...@gmail.com>:
> >> 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 < 1000000 | 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
> `<C-c>`, so `while 1` may even be better for a quick test: if
> everything is fine, memory usage will drop after `<C-c>`, 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 < 1000000 | 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 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.

Raspunde prin e-mail lui