Actually the tail call optimisation is done for all last calls not just recursive calls. It is sometimes called last-call optimisation. So you can write:
defmodule Foo do
def bar() do
baz()
end
def baz() do
bar()
end
end
which will happily recurse forever without building stack. It also works with inter-module calls.
This is the classic way of implementing state machines: you change state by calling the next state function as a tail call. You could view the Foo
module as implementing a state machine with 2 states bar
and baz
.