2016-07-22 14:12 GMT+03:00 Nikolay Aleksandrovich Pavlov <zyx....@gmail.com>:
> 2016-07-22 14:09 GMT+03:00 Nikolay Aleksandrovich Pavlov <zyx....@gmail.com>:
>> 2016-07-20 21:23 GMT+03:00 Ken Takata <ktakata65...@gmail.com>:
>>> 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.
>>
>> 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  0x00007f85da75b947 in kill () from /lib64/libc.so.6
>> #1  0x0000000000598928 in mch_exit ()
>> #2  0x00000000006c8f87 in getout ()
>> #3  0x000000000059695e in deathtrap ()
>> #4  <signal handler called>
>> #5  0x00007f85da7aa5ba in strlen () from /lib64/libc.so.6
>> #6  0x0000000000474173 in string_quote ()
>> #7  0x00000000004582ac in dict2string ()
>> #8  0x0000000000476aa5 in echo_string_core ()
>> #9  0x000000000047d253 in ex_echo ()
>> #10 0x00000000004c13cb in do_one_cmd ()
>> #11 0x00000000004c51fa in do_cmdline ()
>> #12 0x000000000055f545 in nv_colon ()
>> #13 0x000000000056cb48 in normal_cmd ()
>> #14 0x00000000006c8b65 in main_loop ()
>> #15 0x000000000043c21c in main ()
>> ```
>>
>> When not it crashes and hangs either immediately or when I press :, if
>> I comment garbagecollect() call, but then type it myself and exit, I
>> get
>>
>> ```
>> #0  0x0000000000950a60 in ?? ()
>> #1  0x0000000000594f3f in vim_regexec_both (rmp=0x942860,
>> line=0x94ebd0 <incomplete sequence \354\224>, col=0, nl=0) at
>> regexp.c:8122
>> #2  0x0000000000594ed9 in vim_regexec_prog (prog=0x93eb20
>> <clip_exclude_prog>, ignore_case=0, line=0x94ebd0 <incomplete sequence
>> \354\224>, col=0) at regexp.c:8166
>> #3  0x00000000005837b8 in x_connect_to_server () at os_unix.c:1674
>> #4  0x000000000057d3e9 in get_x11_windis () at os_unix.c:1767
>> #5  0x000000000057d26f in mch_settitle (title=0x983c20 "\340P\230",
>> icon=0x0) at os_unix.c:2150
>> #6  0x000000000057d971 in mch_restore_title (which=3) at os_unix.c:2228
>> #7  0x000000000057eb2c in mch_exit (r=1) at os_unix.c:3279
>> #8  0x00000000006a8544 in getout (exitval=1) at main.c:1493
>> #9  0x000000000052c7cb in preserve_exit () at misc1.c:9494
>> #10 0x00000000005847bd in deathtrap (sigarg=11) at os_unix.c:1164
>> #11 <signal handler called>
>> #12 0x00007fa18d008d5a in malloc_consolidate () from /lib64/libc.so.6
>> #13 0x00007fa18d009a70 in _int_free () from /lib64/libc.so.6
>> #14 0x00000000005312ee in vim_free (x=0x968660) at misc2.c:1698
>> #15 0x00000000005d4c73 in free_screenlines () at screen.c:8833
>> #16 0x000000000053126f in free_all_mem () at misc2.c:1231
>> #17 0x000000000057eba6 in mch_exit (r=0) at os_unix.c:3330
>> #18 0x00000000006a8544 in getout (exitval=0) at main.c:1493
>> #19 0x00000000004b76c1 in ex_quit_all (eap=0x7ffda0419aa8) at ex_docmd.c:7249
>> #20 0x00000000004a8b47 in do_one_cmd (cmdlinep=0x7ffda041a208,
>> sourcing=0, cstack=0x7ffda0419d50, fgetline=0x4c83e0 <getexline>,
>> cookie=0x0) at ex_docmd.c:2925
>> #21 0x00000000004a4a70 in do_cmdline (cmdline=0x0, fgetline=0x4c83e0
>> <getexline>, cookie=0x0, flags=0) at ex_docmd.c:1110
>> #22 0x000000000054e548 in nv_colon (cap=0x7ffda041a348) at normal.c:5323
>> #23 0x0000000000545222 in normal_cmd (oap=0x7ffda041a3e8, toplevel=1)
>> at normal.c:1149
>> #24 0x00000000006a8ed4 in main_loop (cmdwin=0, noexmode=0) at main.c:1308
>> #25 0x00000000006a5509 in main (argc=8, argv=0x7ffda041a738) at main.c:874
>> ```
>>
>> When hanging bt is
>>
>> ```
>> #0  0x00007f5203cd092b in __lll_lock_wait_private () from /lib64/libc.so.6
>> #1  0x00007f5203c54766 in malloc () from /lib64/libc.so.6
>> #2  0x0000000000530b5e in lalloc (size=14560, message=1) at misc2.c:920
>> #3  0x00000000005bd796 in nfa_regmatch (prog=0x950a70, start=0x950c50,
>> submatch=0x942568, m=0x942378) at ./regexp_nfa.c:5547
>> #4  0x00000000005bd1d6 in nfa_regtry (prog=0x950a70, col=0, tm=0x0) at
>> ./regexp_nfa.c:6967
>> #5  0x00000000005bcce0 in nfa_regexec_both (line=0x94ebd0
>> "konsole-256color", startcol=0, tm=0x0) at ./regexp_nfa.c:7159
>> #6  0x00000000005a4fab in nfa_regexec_nl (rmp=0x942860, line=0x94ebd0
>> "konsole-256color", col=0, line_lbr=0) at ./regexp_nfa.c:7318
>> #7  0x0000000000594f3f in vim_regexec_both (rmp=0x942860,
>> line=0x94ebd0 "konsole-256color", col=0, nl=0) at regexp.c:8122
>> #8  0x0000000000594ed9 in vim_regexec_prog (prog=0x93eb20
>> <clip_exclude_prog>, ignore_case=0, line=0x94ebd0 "konsole-256color",
>> col=0) at regexp.c:8166
>> #9  0x00000000005837b8 in x_connect_to_server () at os_unix.c:1674
>> #10 0x000000000057d3e9 in get_x11_windis () at os_unix.c:1767
>> #11 0x000000000057d26f in mch_settitle (title=0x983c20 "[Нет имени] -
>> VIM", icon=0x0) at os_unix.c:2150
>> #12 0x000000000057d971 in mch_restore_title (which=3) at os_unix.c:2228
>> #13 0x000000000057eb2c in mch_exit (r=1) at os_unix.c:3279
>> #14 0x00000000006a8544 in getout (exitval=1) at main.c:1493
>> #15 0x000000000052c7cb in preserve_exit () at misc1.c:9494
>> #16 0x00000000005847bd in deathtrap (sigarg=11) at os_unix.c:1164
>> #17 <signal handler called>
>> #18 0x00007f5203c53184 in _int_malloc () from /lib64/libc.so.6
>> #19 0x00007f5203c54778 in malloc () from /lib64/libc.so.6
>> #20 0x0000000000530b5e in lalloc (size=29, message=1) at misc2.c:920
>> #21 0x0000000000530af8 in alloc (size=29) at misc2.c:818
>> #22 0x0000000000642c53 in call_user_func (fp=0x9b02b0, argcount=0,
>> argvars=0x7ffd62dee650, rettv=0x7ffd62deee60, firstline=1, lastline=1,
>> selfdict=0x0) at userfunc.c:897
>> #23 0x0000000000641ac3 in call_func (funcname=0x9b03f0 "<lambda>1",
>> len=9, rettv=0x7ffd62deee60, argcount_in=0, argvars_in=0x7ffd62dee650,
>> firstline=1, lastline=1, doesrange=0x7ffd62dee8f4, evaluate=1,
>> partial=0x0, selfdict_in=0x0)
>>     at userfunc.c:1347
>> #24 0x00000000006414da in get_func_tv (name=0x9b03f0 "<lambda>1",
>> len=9, rettv=0x7ffd62deee60, arg=0x7ffd62deee70, firstline=1,
>> lastline=1, doesrange=0x7ffd62dee8f4, evaluate=1, partial=0x0,
>> selfdict=0x0) at userfunc.c:514
>> #25 0x0000000000471f66 in eval7 (arg=0x7ffd62deee70,
>> rettv=0x7ffd62deee60, evaluate=1, want_string=0) at eval.c:4344
>> #26 0x00000000004715bf in eval6 (arg=0x7ffd62deee70,
>> rettv=0x7ffd62deee60, evaluate=1, want_string=0) at eval.c:3978
>> #27 0x0000000000471185 in eval5 (arg=0x7ffd62deee70,
>> rettv=0x7ffd62deee60, evaluate=1) at eval.c:3794
>> #28 0x00000000004704db in eval4 (arg=0x7ffd62deee70,
>> rettv=0x7ffd62deee60, evaluate=1) at eval.c:3493
>> #29 0x00000000004702ea in eval3 (arg=0x7ffd62deee70,
>> rettv=0x7ffd62deee60, evaluate=1) at eval.c:3410
>> #30 0x000000000046608a in eval2 (arg=0x7ffd62deee70,
>> rettv=0x7ffd62deee60, evaluate=1) at eval.c:3342
>> #31 0x0000000000461b13 in eval1 (arg=0x7ffd62deee70,
>> rettv=0x7ffd62deee60, evaluate=1) at eval.c:3270
>> #32 0x000000000046aec6 in ex_echo (eap=0x7ffd62def0e8) at eval.c:8166
>> #33 0x00000000004a8b47 in do_one_cmd (cmdlinep=0x7ffd62def848,
>> sourcing=0, cstack=0x7ffd62def390, fgetline=0x4c83e0 <getexline>,
>> cookie=0x0) at ex_docmd.c:2925
>> #34 0x00000000004a4a70 in do_cmdline (cmdline=0x0, fgetline=0x4c83e0
>> <getexline>, cookie=0x0, flags=0) at ex_docmd.c:1110
>> #35 0x000000000054e548 in nv_colon (cap=0x7ffd62def988) at normal.c:5323
>> #36 0x0000000000545222 in normal_cmd (oap=0x7ffd62defa28, toplevel=1)
>> at normal.c:1149
>> #37 0x00000000006a8ed4 in main_loop (cmdwin=0, noexmode=0) at main.c:1308
>> #38 0x00000000006a5509 in main (argc=8, argv=0x7ffd62defd78) at main.c:874
>> ```
>
> Last two backtraces are from 4c2524dd2403 plus your patch.

(7.4.2089, using mercurial mirror)

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

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