Recursion: the programming technique that looks simple until you understand it. And then too.
Fundamentals 14 min Beginner May 3, 2026
What if a function could solve a problem by asking a slightly simpler version of itself for help — over and over, until the answer is trivially obvious? That is recursion.
The developer Q&A platform "Stack Overflow" was named after exactly the crash that happens when a recursion never ends. That alone shows how important — and how common — this concept is in computer science.
The Self-Calling Function
Recursion
AnalogyDefinition
Recursion works like Matryoshka dolls: You open the largest doll and find a smaller one inside with a note: "Do the same with me." This continues until someone opens the smallest doll and finds a number — the base case. Then the number travels back up: each person takes the result, adds their own contribution, and passes it on.
Analogy:
Recursion works like Matryoshka dolls: You open the largest doll and find a smaller one inside with a note: "Do the same with me." This continues until someone opens the smallest doll and finds a number — the base case. Then the number travels back up: each person takes the result, adds their own contribution, and passes it on.
Definition:
Recursion is a technique where a function calls itself to solve a problem by reducing it to a smaller instance of the same problem. Every recursive function has exactly two components: (1) The recursive case — the function calls itself with a smaller input. (2) The base case — the function returns a value directly without calling itself again. Each call creates a new stack frame on the call stack — a memory slot for parameters and local variables.
The Matryoshka analogy breaks because in real life, no one "remembers" the context of the previous doll. In a program, each stack frame explicitly stores its own state (parameters, local variables) and actively waits for the result from the call below.
Example: Factorial (5!) — Descent and Return
1
factorial(5) calls factorial(4) — remembers 5 * ?
2
factorial(4) calls factorial(3) — remembers 4 * ?
3
factorial(3) calls factorial(2) — remembers 3 * ?
4
factorial(2) calls factorial(1) — remembers 2 * ?
5
factorial(1) reaches BASE CASE → returns 1
6
factorial(2) = 2 * 1 = 2
7
factorial(3) = 3 * 2 = 6
8
factorial(4) = 4 * 6 = 24
9
factorial(5) = 5 * 24 = 120
At peak depth, 5 stack frames exist simultaneously in memory, each with its own copy of n. When the base case returns, frames are removed one by one in reverse order — the so-called "unwinding."
Python Code: Factorial
def factorial(n):
if n <= 1: # Base case
return 1
return n * factorial(n - 1) # Recursive case
print(factorial(5)) # Output: 120
The Base Case: Your Safety Net
The base case is the single most critical line in any recursive function. It defines WHEN the function stops calling itself and WHAT it returns at that point. Without a base case, the function calls itself infinitely — each call adds a stack frame until available memory is exhausted.
Imagine a circular maze with no exit signs. Without a marker, a person wanders endlessly in circles. Place a red marker at one specific spot with the instruction "When you see the red marker, stop walking" — and infinite wandering becomes a finite search. That marker is the base case.
Countdown: Without vs. With Base Case
# BROKEN — no base case
def countdown(n):
print(n)
countdown(n - 1) # calls forever: 3, 2, 1, 0, -1, ...
# → RecursionError after ~1000 calls
# CORRECT — base case stops at 0
def countdown(n):
if n <= 0: # Base case
print(0)
return # STOP
print(n)
countdown(n - 1) # Recursive case
The difference is a single if check — but it decides between a working program and a crash. The base case must appear BEFORE the recursive call in the function body.
Common Mistake: Increasing the Recursion Limit
sys.setrecursionlimit(10000) does not add more memory — it just delays the crash. If the problem requires truly unbounded depth, the real fix is either a proper base case or switching to an iterative approach.
Where Loops Fail: Recursion for Hierarchies
Loops (for, while) excel at processing linear sequences: iterate through a list, count from 1 to n. But when the data structure itself is nested to unknown depth — folders within folders, HTML elements within elements, branches of a game tree — a simple loop cannot see deeper than one level.
You need to find all .pdf files on a hard drive. Checking each file in the top-level folder is easy. But some items are folders containing more files and folders, nested to unknown depth. The recursive approach: "Open the folder. Check each item. If it is a file, evaluate it. If it is a folder, apply the same procedure to it."
Recursive (implicit stack)
def find_pdfs(folder):
results = []
for item in os.listdir(folder):
path = os.path.join(folder, item)
if os.path.isfile(path) and path.endswith('.pdf'):
results.append(path)
elif os.path.isdir(path):
results.extend(find_pdfs(path))
return results
Shorter, reads like the problem description. Uses the call stack implicitly.
Iterative (explicit stack)
def find_pdfs_iterative(root):
results = []
stack = [root]
while stack:
folder = stack.pop()
for item in os.listdir(folder):
path = os.path.join(folder, item)
if os.path.isfile(path) and path.endswith('.pdf'):
results.append(path)
elif os.path.isdir(path):
stack.append(path)
return results
Avoids Python's recursion limit for very deep directories.
Recursion in the Wild
File Search Searching folder structures of unknown depth
HTML Parsing Traversing nested DOM elements
JSON Traversal Processing nested objects and arrays
Game Trees MinMax algorithm for chess, tic-tac-toe
Step through the call tree of fib(5). Observe how the function keeps calling itself until it reaches a base case — and how the results then travel back up the tree. Pay special attention to how often fib(2) and fib(3) are computed multiple times.
Step 1 / 13fib(5)
Synthesis: Recursion Is Not Magic
Recursion is not magic — it is a disciplined delegation pattern: break the problem down, trust your future self to handle the smaller piece, and define the point where delegation stops.
In AI, recursion is everywhere: tree traversals, depth-first search (DFS), divide-and-conquer algorithms, and game-tree evaluation (MinMax) — all are built on the recursive principle.
Key Takeaways
Recursion = a function calls itself to reduce a problem to a smaller version of the same problem.
Every recursive function needs two parts: the base case (when to stop) and the recursive case (how to continue).
Without a base case: infinite calls → stack overflow → RecursionError. The base case is the safety net.
Recursion is ideal for hierarchical problems (folders, trees, nested structures) where the depth is unknown.
Recursion and iteration are equivalent, but recursion maps hierarchical problems more naturally.
Quiz: Recursion
Question 1 / 4
Not completed
What are the two essential parts of every recursive function?
1. What are the two essential parts of every recursive function?
☐ A) A loop and a counter
☐ B) A base case and a recursive case
☐ C) An input and an output
☐ D) A variable and a constant
2. factorial(4) is called. How many stack frames exist at peak depth?
☐ A) 1
☐ B) 3
☐ C) 4
☐ D) 8
3. A countdown function has no base case. What happens when you call countdown(3)?
☐ A) It counts to 0 and stops
☐ B) It counts forever until Python raises a RecursionError after ~1000 calls
☐ C) It prints 3 once and stops
☐ D) It does nothing
4. You need to find all .txt files in a folder with subfolders of unknown depth. Why is recursion better suited than a simple for loop?
☐ A) Recursion is always faster than loops
☐ B) A simple loop can only see one level, but recursion can descend into subfolders of unknown depth
☐ C) Loops cannot read files
☐ D) Recursion uses less memory
Answer Key: 1) B · 2) C · 3) B · 4) B
Checkpoint: Test Your Knowledge
Explain what happens in memory when factorial(4) is called. How many stack frames exist at peak depth?
Why does countdown(3) without a base case crash? What exactly happens after ~1000 calls?
Find all .txt files in a folder with subfolders — describe the recursive approach in your own words.