[erlang-questions] Idiomatic Erlang, style/performance question
Mats Cronqvist
mats.cronqvist@REDACTED
Mon Jun 23 15:01:26 CEST 2008
Richard A. O'Keefe wrote:
> On 20 Jun 2008, at 8:16 pm, Dominic Williams wrote:
>
>
>> Hello,
>>
>> ROK wrote:
>>
>>> I prefer the term "Tail-Call Optimisation" because it is more
>>> accurate.
>>> The idea (as explained in "Lambda - the Ultimate Goto") is that if
>>> the
>>> dynamically last thing a function does (in any language) is to return
>>> the result of another function call, then there is no point in
>>> keeping
>>> the current stack frame. You might as well arrange for the new
>>> function to return directly to the original caller. Think of *all*
>>> tail calls as "argument binding + GOTO".
>>>
>> Is the optimisation possible even when the tail call is not to the
>> same
>> function?
>>
>
> That's precisely why I prefer to call it tail CALL optimisation.
> It is not in any way limited to recursion.
>
for illustration, consider this wonderful code(somewhat obfuscated to
prevent inlining);
-module('foo').
-author('Mats Cronqvist').
-export([a/1]).
a(X) -> c(b(X)).
b(X) -> X/element(3,now()).
c(X) -> float_to_list(X)/element(2,now()).
when it crashes in c/1, the stack does not contain a/1. when it
crashes in b/1, the stack will show that b/1 was called from a/1.
(erl@REDACTED)19> foo:a(1).
** exited: {badarith,[{foo,c,1},
{erl_eval,do_apply,5},
{shell,exprs,6},
{shell,eval_loop,3}]} **
(erl@REDACTED)20> foo:a(x).
** exited: {badarith,[{foo,b,1},
{foo,a,1},
{erl_eval,do_apply,5},
{shell,exprs,6},
{shell,eval_loop,3}]} **
the stack only contains frames for functions that we are supposed to
return to. the call to b/1 will return to a/1, but the call to c/1 won't.
mats
More information about the erlang-questions
mailing list