The setup is almost a joke: evaluate an arithmetic expression using a binary tree. Three nodes, 96 bytes, done by lunch. But the author's mind works like a compiler with no optimization passes — every abstraction begs to be generalized, every generalization demands infrastructure, and every piece of infrastructure reveals a new problem. The result is a full language runtime built from the bottom up in C, documented in real time as a blog post that reads like a debugger trace of someone's thought process. The key intellectual move happens early and drives everything else. Instead of hard-coding Add, Sub, Mul, Div as separate AST node types, the author notices they all share the same shape: Expr × Expr → Expr. So the evaluator doesn't need to know what a function does — only how to apply one. That single abstraction collapses arithmetic into function application, which is the foundational move of lambda calculus. The author may or may not know they're rediscovering Church's insight from 1936; either way, they're doing it from first principles in a struct with two pointers and a tagged union. From there, the scope creep is inevitable and honestly kind of beautiful. Variables require a hash table. C doesn't have one, so they build one. Functions-as-values require closures. Closures require representing function bodies as walkable AST nodes rather than opaque C function pointers — a design decision that lands them squarely in interpreter territory. The memory pressure from naive malloc (48 bytes per node including metadata) demands an arena allocator. The arena's fixed size demands a chunk allocator with linked blocks. And fib(40) spawning 1.3 billion nodes at 48 bytes each — roughly 12 GB before OOM — demands a garbage collector. The writing style is the secret weapon here. This isn't a tutorial and it isn't a reference. It's a narrative of discovery, complete with emoji reactions, ASCII art memory layouts, and the specific moment of dread when fib(10) eats 40 MB of RAM. The author shows you the RAM-vs-fib(n) curve as an ASCII chart and lets the exponential speak for itself. Every technical decision is motivated by a concrete failure, not by theory. You understand WHY arenas exist because you just watched malloc metadata eat your memory budget. What makes this work as a piece of writing — not just as a project — is that it accidentally demonstrates the entire dependency chain of language implementation. Parser? Not yet, they're hand-constructing ASTs. But they need closures, environments, memory management, and garbage collection just to evaluate fib(5) without crashing. The post is a live proof that language runtimes aren't over-engineered — they're the minimum viable response to the problems that arise when you take 'functions are values' seriously. The piece cuts off before the garbage collector implementation and the punchline (does it actually evaluate 1+1?), which means this is Part 1 of a series. The momentum is real. Whether the author can sustain this quality of narration through GC mark-and-sweep algorithms and FFI plumbing will determine whether this becomes a genuine teaching resource or a fun half-finished side project. Right now, it's the best kind of technical blog post: one where you learn something structural about computing by watching someone rediscover it the hard way.