Greenspun's Tenth Rule¶
The aphorism that any sufficiently complicated C or Fortran program contains an ad hoc, bug-ridden implementation of half of Common Lisp — because features a language withholds do not vanish but migrate inside the program as defective re-implementations.
Core Idea¶
Greenspun's Tenth Rule (the "tenth" is the joke — there are no preceding nine) states: any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp. When a base language withholds features a growing program needs — first-class functions, runtime code construction, macros, symbolic manipulation — those features do not disappear; they migrate inside the program, assembled piecemeal from what the language provides, and arrive defective. The choice is not whether the feature exists but where it lives and how cleanly it is built.
Scope of Application¶
The rule lives within programming-language design and the software-engineering culture around it, across contexts where programs are written in a language too narrow for their domain.
- Programming-language theory — expressiveness-versus-simplicity debates and rationales for macros and first-class functions.
- Software-architecture critique — the reviewer's label for ad-hoc rule engines, config DSLs, homegrown templating.
- Programmer folklore — preserved in collections of programming wisdom as an argument for expressive base languages.
- Its dual neighborhood — paired with the Lisp tarpit and the Turing tarpit as the ends of the expressivity trade-off.
Clarity¶
Naming the rule makes a scattered set of code smells legible as one diagnosis. A hand-rolled rules engine, a templater with its own conditional syntax, and a reflection-heavy plugin loader stop being unrelated lapses of judgment and become one recurring failure: withheld features migrating inside the program as defective re-implementations. That moves the design argument off the personal axis (this subsystem is badly built) onto the structural one (the expressivity gap forced it into existence), where it can be resolved — and sharpens the question to where should this capability live.
Manages Complexity¶
A sprawl of seemingly unrelated subsystems collapses to a single generator: each is the smallest local workaround for one capability the base language withheld, and their union is a defective re-implementation of the missing features. The maintainer tracks one quantity — the expressivity gap between language and domain — from which the shape follows: the wider the gap, the larger the internalized re-implementations, and maintenance cost scales with the size of the accreted embedded language, not the count of feature requests.
Abstract Reasoning¶
The rule licenses a diagnostic (read scattered odd subsystems back to one generator, the expressivity gap; run it in reverse to predict an embedded language's presence), a quantitative-predictive move (cost scales with the accreted language's size), an interventionist move keyed to its central branch (the capability will be internalized; the only variable is deliberately or accidentally), and a boundary-drawing move (it bites only past a complexity threshold and only when the domain demands the withheld expressivity).
Knowledge Transfer¶
Within programming-language design the rule transfers as mechanism — the diagnostic, the quantitative prediction, the deliberate-versus-accidental branch, and the boundary conditions carry intact across PL-theory debates, architecture critique, and its dual concepts, because each is the same substrate. Beyond software the general pattern travels as the parent it specializes — the inner-platform effect (a system denied an abstraction grows a worse re-implementation of it) — recurring in a spreadsheet-turned-database or an org reinventing a worse HR system. Loose invocations there are metaphor; the Lisp-and-C cargo stays home. Were an inner_platform_effect prime added, Greenspun's tenth would be its named PL specialization.
Relationships to Other Abstractions¶
Current abstraction Greenspun's Tenth Rule Domain-specific
Parents (1) — more general patterns this builds on
-
Greenspun's Tenth Rule is a kind of Inner-Platform Effect Domain-specific
Greenspun's Tenth Rule is the programming-language species of the inner-platform effect, where a program lacking sufficiently expressive host abstractions grows an ad hoc, incomplete language implementation inside itself.
Hierarchy paths (3) — routes to 2 parentless roots
- Greenspun's Tenth Rule → Inner-Platform Effect → Platform Design → Modularity → Decomposition
- Greenspun's Tenth Rule → Inner-Platform Effect → Platform Design → Interface → Boundary
- Greenspun's Tenth Rule → Inner-Platform Effect → Platform Design → Open-Closed Principle → Modularity → Decomposition
Neighborhood in Abstraction Space¶
Greenspun's Tenth Rule sits in a crowded region of the domain-specific corpus (21st percentile for distinctiveness): several abstractions share nearly its structure, so a description that fits it tends to fit its neighbors too.
Family — Software Evolution & Entropy (7 abstractions)
Nearest neighbors
- Inner-Platform Effect — 0.89
- Lazy Class — 0.87
- Primitive Obsession — 0.86
- Software Entropy — 0.86
- Type Inference — 0.84
Computed from structural-signature embeddings · 2026-07-12