iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
To make an anonymous function recurse in Elixir, pass the function itself as an argument and call that argument with dot syntax, such as recur.(recur, next_value). An fn does not acquire a self-reference automatically, and the capture operator & does not create one.
How to write a recursive anonymous function
Elixir anonymous functions are defined with fn ... end and invoked by placing a dot between the function value and its arguments. The self-argument technique below applies that syntax: one parameter holds the function value, and each recursive call passes it along again.
factorial = fn recur, n ->
if n <= 1 do
1
else
n * recur.(recur, n - 1)
end
end
factorial.(factorial, 5)
In this illustration, recur is an ordinary argument, not a special Elixir keyword. The initial call supplies the function as that argument; the recursive branch calls it with recur.(recur, n - 1). The result for the example input is 120.
The example uses 1 as its stopping boundary and assumes a nonnegative integer input. Decide explicitly how your code should handle negative values, non-integers, or other inputs outside that assumption. The construction is an application of Elixir’s documented anonymous-function and invocation syntax, not a specially designated recursion feature. See the Elixir Function module documentation and source and Kernel.SpecialForms in Elixir v1.20.2.
#1 Best Overall
Why the function needs a self argument
A named local function can refer to its name in its own body. An anonymous function value has no declared name to call that way. Passing the function into itself gives the body a reference it can invoke on the next step.
That reference must be passed again with every recursive call. Omitting it—for example, calling recur.(n - 1) when the function expects both recur and n—does not match the function’s arity.
How invocation and captures differ
f.(x)invokes a function value. The dot is part of the call syntax for a value stored in a variable.&String.length/1captures an existing named function as a function value.&(&1 + &2)creates a function using argument placeholders.
Neither form of & supplies an automatic self-reference. The capture operator’s forms and behavior are described in the Elixir v1.20.2 Kernel.SpecialForms reference. For captured named functions in hot-code-reloading environments, local and remote captures have different dispatch behavior: a local capture uses the version present when it was created, while a remote capture dispatches to the current version. That distinction concerns captured functions, not the self-argument recursion pattern.
When named recursion is clearer
If the operation is a stable, reusable part of a module, a named function with clauses is often easier to read. Pattern matching can make the base case and recursive step visible directly. For example, list length can be expressed with an empty-list clause and a nonempty-list clause that recurses on the tail:
Rank #3
def length([]), do: 0
def length([_head | tail]), do: 1 + length(tail)
This pattern is illustrated in Elixir School’s Functions lesson. Unlike the anonymous example, the recursive call uses the function’s name rather than receiving the function as a value.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Choosing between the two approaches
| Consideration | Anonymous function with self argument | Named recursive function |
|---|---|---|
| Recursive reference | Passed explicitly as an argument and supplied again at each recursive call. | Uses the function’s name. |
| Base case and progress | Written inside the anonymous function’s body; the example uses a conditional. | Can be separated into pattern-matched clauses, such as empty and nonempty lists. |
| Passing behavior as a value | Useful when the function itself needs to be carried as a value. | Appropriate when a named operation makes reuse and intent clearer. |
| Syntax reference | Elixir Function module documents anonymous functions and dot invocation; the self-argument pattern is an illustrative construction. | Elixir School’s Functions lesson demonstrates named recursion with list length. |
Whichever form you use, make the stopping condition and the change that moves each call toward it obvious. If those details are hard to see in an anonymous function, a named function with clauses is likely the clearer representation.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Recommended Free Tools

