lfe_shell, good to know, set, lambda, grows in size

20 views
Skip to first unread message

Mats

unread,
Apr 7, 2013, 4:20:19 PM4/7/13
to lisp-flavo...@googlegroups.com
Greetings!

I just noticed what first looked like a bug[1]. And then.. not a bug, but something to just watch out for.

To the point:
When "set" is used with "lambda" in lfe_shell, lambda will grow in size every time you run it [1]. People may want to be aware of this since it will sneak up on you very subtle. Suddenly you wonder why the shell is lagging (lags since lambda grow in size.)  If you plan to send it over the network, it will take even more time.  Why do you want to run set and lambda? - it's a fast way to test out functions. 

I found an (ugly) way around this growing thing. My solution is to add "(eval ' " before the lambda, then it will not grow, just stay very small [2]. Eval take a list that is not capturing anything from the shell environment. Then you can keep building stuff in the shell and feel free (but a bit dirty for the eval, of course.)

TL;DR Good to know. "Set" and "lambda" grow in size when used in shell, see [1]. Lambdas capture shell environment.

- Mats

[1]
> (set zero (lambda () (lambda (s) (lambda (x) x))))
#Fun<lfe_eval.21.102758147>
> (size (: erlang term_to_binary zero))
2700
> (set zero (lambda () (lambda (s) (lambda (x) x))))
#Fun<lfe_eval.21.102758147>
> (size (: erlang term_to_binary zero))
12902
> (set zero (lambda () (lambda (s) (lambda (x) x))))
#Fun<lfe_eval.21.102758147>
> (size (: erlang term_to_binary zero))
53716
> (set zero (lambda () (lambda (s) (lambda (x) x))))
#Fun<lfe_eval.21.102758147>
> (size (: erlang term_to_binary zero))
216972

[2]
> (set zero (eval '(lambda ()(lambda (s) (lambda (x) x)))))
#Fun<lfe_eval.21.102758147>
> (size (: erlang term_to_binary zero))
136

rvirding

unread,
Apr 9, 2013, 8:03:21 PM4/9/13
to lisp-flavo...@googlegroups.com
No, it is not a bug. A shell lambda inherits the whole shell environment in which it was created so it is quite natural that it grows. Part of the shell environment are the variable bindings. Unfortunately when doing a (set ...) the value, in this case the lambda, is evaluated first so it will get the old variable binding even though it is replaced immediately.

An alternative would be to go through the lambda and only include the parts of the environment actually used but is would slow things down. It would also do the same thing for all interpreted code.

Erlang does it the same way.

Robert
Reply all
Reply to author
Forward
0 new messages