Neural DownloadNEURAL DOWNLOAD
← cd ../blog

You Don't Hate Recursion. You Were Taught It Wrong.

Recursion visualized from the ground up. Watch the call stack build, see Fibonacci branch into a tree, and understand why memoization changes everything.

recursionrecursive functioncall stackstack framesfibonaccimemoization
Share

Three lines of code drew a Sierpinski triangle. A function that draws a triangle, then calls itself three times — each time smaller, each time nested inside the last. That's not a loop. That's recursion. And every tutorial explains it wrong.

The Real Mental Model

They tell you recursion is "a function calling itself." Technically true. Completely useless. Here's what actually happens.

When factorial(3) runs, the machine doesn't just re-enter the function. It builds an entirely new world — a private copy with its own variables, its own state, sealed off from the original. That copy builds another copy. And another. Until you hit the floor.

The code looks like one function. At runtime, four separate worlds exist simultaneously — stacked in memory, each frozen at a different moment, each holding a different value of n.

The Call Stack: Dreams Inside Dreams

Think of the call stack like dream levels in Inception. Every function call pushes a new frame — a new level with its own private memory. When a function calls itself, it's dreaming inside a dream.

For factorial(4), five levels stack up. Every level is frozen, waiting. The only one running is the one at the very top: factorial(0), which returns 1. That's the base case — the kick that starts the chain reaction.

Then the unwinding begins. Each frozen world wakes up just long enough to do its piece and pass the result down: 1 * 1 * 2 * 3 * 4 = 24. The answer cascades back through five frozen worlds.

No base case? No kick. The stack grows until Python cuts you off at 1,000 frames, or C exhausts its 8MB limit. Stack overflow. (Yes, the website is named after exactly this.)

When One Call Becomes Two: The Tree Explodes

Factorial is clean — one call per level. But fibonacci calls itself twice, and that changes everything.

fib(5) spawns a tree. fib(3) appears twice. fib(2) appears three times. fib(1) appears five times. The function has no memory — it doesn't know it's repeating itself.

InputCalls (naive)Calls (memoized)
fib(5)159
fib(10)17719
fib(20)21,89139
fib(30)2,692,53759

The fix is one dictionary. Before computing anything, check: have I seen this input before? If yes, return instantly. Every duplicate branch vanishes. 2.7 million calls become 59.

Past fib(100), the naive version would take longer than the age of the universe. The memoized version? Microseconds.

Why Not Just Use a Loop?

For factorial, sure. But try writing a loop that walks a directory tree — folders containing folders of unknown depth and branching. Or nested JSON. Or a Git object tree. Or React components rendering components.

The structure itself is recursive — it contains smaller copies of itself. The only natural way to traverse it is recursion. It's the native language for self-similar structure, and once you see it, you see it everywhere.

Watch the full animated breakdown: Recursion — What Every Tutorial Gets Wrong