[erlang-questions] Tail call optimization

Dmytro Lytovchenko <>
Mon Oct 17 14:36:08 CEST 2016


There is nothing about recursion in documentation.

Your module:
-module(tc).
-export([a/0]).
a() -> b().
b() -> c().
c() -> z().
z() -> self().

Compiles to (memory dump):
00007F07875A2DA8: i_func_info_IaaI 0 tc a 0.
00007F07875A2DD0: i_call_only_f tc:b/0.

00007F07875A2DE0: i_func_info_IaaI 0 tc b 0.
00007F07875A2E08: i_call_only_f tc:c/0.

00007F07875A2E18: i_func_info_IaaI 0 tc c 0.
00007F07875A2E40: i_call_only_f tc:z/0.

00007F07875A2E50: i_func_info_IaaI 0 tc z 0.
00007F07875A2E78: self_r x(0).
00007F07875A2E80: return.

Note the call_only functions. These are the tail calls.


2016-10-17 14:28 GMT+02:00 Salikhov Dinislam <
>:

> The confusing thing is that the doc says about tail *recursive* call.
> For example, if I have a call chain:
>     a() ->
>         % some code
>         b().
>     b() ->
>         % some code
>         c().
>     % ...
>     y() ->
>         %some code
>         z().
> Recursion is *not* involved here. And I'd like to know if erlang requires
> (and guarantees) that all tail callees in the chain above use the stack of
> the caller.
> AFAIU, compiler is free to not apply the optimization if it is not stated
> in the specification (and it is pure luck that the compiler does).
>
> Salikhov Dinislam
>
>
> On 10/17/2016 03:00 PM, Dmytro Lytovchenko wrote:
>
> In the doc page you linked:
> > If the last expression of a function body is a function call, a *tail
> recursive* call is done.
>
> Compiler will replace call opcode with a tail call (call_last,
> call_ext_last, apply_last). You can check it with "erl -S test.erl" to see
> assembly, and in erl console: "l(modulename)." to load the module then
> "erts_debug:df(modulename)." to create disassembly from BEAM VM memory (it
> will be a bit different from the erl -S output).
>
> See that your calls are replaced with one of: call_last, call_ext_last,
> apply_last.
>
> 2016-10-17 10:58 GMT+02:00 Salikhov Dinislam <
> com>:
>
>> Hello.
>>
>> Erlang guarantees tail recursion optimization and states it in the
>> documentation:
>> http://erlang.org/doc/reference_manual/functions.html#id78464
>>
>> Does erlang guarantee that tail call optimization is done in a generic
>> case, without recursion?
>> Say, we have a function calling a function from another module as its
>> final statement:
>>     alpha() ->
>>         xxx:beta().
>> Is it guaranteed that xxx:beta() will use the stack of alpha() regardless
>> whether recursion is involved.
>> I mean whether the language guarantees it rather than virtual machine may
>> provide such optimization.
>>
>> Thanks in advance,
>> Salikhov Dinislam
>>
>> _______________________________________________
>> erlang-questions mailing list
>> 
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20161017/bb94f834/attachment.html>


More information about the erlang-questions mailing list