liveBook · Manning

Tail-call optimization

As explained in Elixir in Action, Third Edition

Tail-call optimization is a compiler or runtime optimization that reuses a caller's stack frame when its final operation is a function call.

Tail-call optimization reuses the current call’s stack space when the final operation is another function call. Elixir, through Erlang, can treat that call like a jump instead of pushing a new stack frame, so tail-recursive functions can handle arbitrarily large iterations without consuming additional memory. section 3.4.1 section 3.4.2

A call is eligible for this optimization when:

  • The function’s final operation calls another function or calls itself. section 3.4.2
  • The caller returns the callee’s result directly, allowing execution to jump without preserving additional caller state. section 3.4.2
  • Recursive work carries intermediate results in arguments, such as current_sum, rather than performing more computation after the recursive call. section 3.4.2

Tail-recursive list summation

ListHelper.sum/1 initializes the accumulated value, while private do_sum/2 handles the recursion. For a nonempty list, it computes a new sum and calls itself with the remaining tail; for an empty list, it returns the accumulator. Both [1, 2, 3] and [] produce the expected results.

Not every recursive function is tail recursive. In head + sum(tail), the addition remains after the recursive call returns; likewise, 1 + another_fun(...) prevents the call from being the final operation. Tail recursion is therefore a structural property of the last expression, not merely a synonym for recursion.

How Elixir in Action, Third Edition covers it

How deep it goes
Explains stack-frame reuse and tail-call structure, then stops short of compiler implementation details.
Examples
Demonstrates natural-number printing, ordinary list summation, and accumulator-based tail-recursive list summation.
What it assumes
Assumes familiarity with function calls and recursion while teaching tail-call position through Elixir examples.
What you can do after
Build it from scratch using an accumulator and a final recursive call to process arbitrarily large iterations.
How it connects
Connects recursion with function calls, stack overflow, accumulators, and iterative control flow.

Also explained in

Compare how 3 books explain tail-call optimization →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Elixir in Action, Third Edition. The section links point to the parts of the book it draws on.