Understanding Recursion with Real Examples

Recursion trips up new programmers not because it’s conceptually hard, but because most introductory examples (factorial, Fibonacci) are things you’d never actually write recursively in production. Seeing it applied to a problem where it’s genuinely the natural solution makes it click.

The Two Things Every Recursive Function Needs

A base case (when to stop) and a recursive case that moves closer to that base case. Skip either one and you get infinite recursion until the call stack overflows.

def factorial(n):
    if n <= 1:          # base case
        return 1
    return n * factorial(n - 1)   # recursive case, moving toward the base case

A Problem Where Recursion Actually Shines: Traversing a Tree

Filesystem directories, DOM trees, JSON with nested objects, org charts — anywhere data naturally nests inside itself, recursion mirrors the problem’s structure far more directly than a manually managed loop and stack would:

import os

def total_size(path):
    if os.path.isfile(path):
        return os.path.getsize(path)

    total = 0
    for entry in os.listdir(path):
        total += total_size(os.path.join(path, entry))
    return total

The Real Cost: Stack Depth

Every recursive call adds a frame to the call stack. Python’s default recursion limit is 1000 calls deep — fine for a directory tree, dangerous for processing a long linked list recursively. When depth is unbounded, either convert to an explicit loop with your own stack, or check whether your language supports tail-call optimization (Python notably does not).

def total_size_iterative(path):
    total = 0
    stack = [path]
    while stack:
        current = stack.pop()
        if os.path.isfile(current):
            total += os.path.getsize(current)
        else:
            stack.extend(os.path.join(current, e) for e in os.listdir(current))
    return total

Both versions solve the same problem — the recursive one reads closer to the problem statement, the iterative one avoids any stack depth concerns. Knowing both, and when to reach for each, is the actual skill worth having.