Tail calls of funs not optimized?

Ondřej Adamovský oa@REDACTED
Mon Mar 29 18:52:02 CEST 2021


Out of curiosity, I was looking at BEAM assembler listings of some of my modules. To my great dismay, I noticed tail fun calls seem to not be optimized. Regular function tail calls are translated to single call_last or call_only instruction, but fun tail call is translated to call_fun instruction followed by deallocate and return instructions. Also, the call_fun instruction is the same regardless of its position in the function body.

Can somebody explain to me why? Or if this still is optimized somehow, then how?

I regularly use a recursive cycle of functions formed by recursive tail calls. With the optimization it effectively uses only one stack frame. It is only natural to vary parts of the cycle using funs depending on options provided to the initial call. If this finding is true, the cycle with funs produces at least one stack frame per cycle which can use up quite substantial portion of memory (or even deplete it in endless cycles).

This should have a big red warning in the documentation, but I did not find any mention of this there or anywhere. Tail call optimization is discussed here https://erlang.org/doc/reference_manual/functions.html#tail-recursion in chapter about functions with no mention of funs. Function call is defined here https://erlang.org/doc/reference_manual/expressions.html#function-calls explicitly stating fun call as a possibility.

Best regards,
Ondřej Adamovský

More information about the erlang-questions mailing list