[erlang-questions] Idiomatic Erlang, style/performance question

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

()19> foo:a(1).
** exited: {badarith,[{foo,c,1},
                      {erl_eval,do_apply,5},
                      {shell,exprs,6},
                      {shell,eval_loop,3}]} **

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