When I compile the following module:
-module(x).
-export([inp/0]).
f(X) ->
g(X).
g(X) ->
error(X).
inp() ->
f(123).
And evaluate x:inp()
I get the following output:
[{x,g,1,[{file,"x.erl"},{line,8}]},
{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,689}]},
{erl_eval,try_clauses,8,[{file,"erl_eval.erl"},{line,919}]},
{shell,exprs,7,[{file,"shell.erl"},{line,686}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]
Where did the calls to f
and inp
go? This behavior makes it significantly harder to track the causes of errors in my case, how can I get the full stacktrace?
I am using OTP24
This is because of Erlang's compiler optimization. The compiler deduces that, in this specific case, functions f()
and inp()
are only used to pass a number to function g()
and they cannot be used for anything else, not even theoretically. So the compiler "optimizes them away" and de facto only compiles function g()
.