← Back to articles

Tail Recursion

Tail recursion is a type of recursion. The recursive call is the last action in the function. Tail recursion can be faster. The compiler can optimize it and use a jump instead of a call. This lowers memory use and CPU work. The program does not need to keep extra stack frames.

Example: a recursive function that calculates factorial in Rust:


fn factorial(n: u64) -> u64 {
    match n {
        0 => 1,
        _ => n * factorial(n - 1),
    }
}

This version is not tail recursion, because the multiplication happens after the recursive call.

Now we change it to tail recursion:


fn factorial(n: u64) -> u64 {
    fn helper(n: u64, acc: u64) -> u64 {
        match n {
            0 => acc,
            _ => helper(n - 1, acc * n),
        }
    }
    helper(n, 1)
}

In this example, we add a helper function. It has an extra argument acc. This argument keeps the result, and all work happens before the recursive call. This lets the compiler optimize the call.

In normal recursion, multiplication happens after the recursive call. This adds extra load to the call stack. In tail recursion, all work happens before the recursive call. This allows optimization.

Tail recursion is not only in Rust. It is also in Python, Java, JavaScript, PHP, C++, and other languages. Tail recursion helps use system resources well. It is useful for big data sets and complex algorithms.