2016-07-20 21:23 GMT+03:00 Ken Takata <[email protected]>:
> Hi,
>
> 2016/7/19 Tue 23:18:30 UTC+9 ZyX wrote:
>> 2016-07-19 17:15 GMT+03:00 Nikolay Aleksandrovich Pavlov <[email protected]>:
>> > 2016-07-19 16:46 GMT+03:00 Ken Takata <[email protected]>:
>> >> 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
```
>
>
>> > 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 [email protected].
> 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 [email protected].
For more options, visit https://groups.google.com/d/optout.