Recursion
A function defined in terms of itself, solving a problem by solving smaller instances of the same problem.
Recursion defines a function in terms of a smaller call to itself, plus a base case that stops the descent. factorial(n) = n * factorial(n - 1), with factorial(0) = 1 as the base case, is the canonical shape: every recursive definition needs exactly this pair — a case that doesn't recurse, and a case that does but moves strictly closer to one that doesn't — or it never terminates.
Recursion is the natural fit for anything with a recursive shape in the data itself: a tree, where each subtree is itself a tree; a nested JSON value, where each value can contain more values of the same kind; a Trie, defined as nodes whose children are tries. Writing a tree traversal iteratively usually means manually managing a stack to remember where to come back to — recursion gets that stack for free from the call stack the language already maintains, which is both its convenience and its risk, since an unbounded or miscounted recursion overflows that same stack.
Tail Call Optimization is the escape hatch for the stack-overflow risk, when a language actually performs it: a tail-recursive function's frames get reused rather than piled up, turning the recursion into constant stack space. Where TCO isn't guaranteed, deeply recursive algorithms are rewritten iteratively, or the recursion depth is bounded so it never approaches the stack limit in practice.
Memoization and recursion are frequent partners: naive recursive Fibonacci recomputes the same subproblems exponentially many times (fib(5) calls fib(3) twice, fib(2) three times, and so on), and caching each fib(n) the first time it's computed turns the same recursive structure into linear work — the technique generalizes to Dynamic Programming, which is recursion with memoization (or its iterative, bottom-up equivalent) applied systematically to problems with overlapping subproblems.
See also2
Finite State Machine
A model with a fixed set of states, one active at a time, and defined transitions between them on each input.
Computation & Algorithms10 connections
Iterator
An object that hands out the elements of a collection or sequence one at a time on request, separating how a sequence is produced from how it's consumed, which lets the same loop walk arrays, trees, files and infinite streams.
Computation & Algorithms7 connections
Linked from7
- BacktrackingComputation & Algorithms
Searching for a solution by making choices one at a time and undoing the latest choice when it leads nowhere, the method behind puzzle solvers, regex engines, and dependency resolvers.
- Call StackComputation & Algorithms
The region of memory where each function call keeps its local variables and the address to return to, and the source of stack traces, stack overflows, and a classic class of security holes.
- Dynamic ProgrammingComputation & Algorithms
Solving a problem by solving each distinct overlapping subproblem exactly once and reusing the results.
- Higher-Order FunctionComputation & Algorithms
A function that takes another function as an argument, returns one, or both.
- Lazy EvaluationComputation & Algorithms
Deferring a computation until its result is actually needed, and then caching it so it never runs twice.
- MemoizationComputation & Algorithms
Caching a function's result against its input so a repeat call with the same input skips recomputation.
- Tail Call OptimizationComputation & Algorithms
Reusing a function's stack frame for a call in tail position so recursion runs in constant stack space.