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.