Chapter 13. Pre-Web Paradigms
Technology changes quickly; people’s minds change slowly. […] The next generation of programmers grows up only being shown one way of thinking about programming. […] They grow up with dogma. And once you grow up with dogma, it’s really hard to break out of it.
— Bret Victor, The Future of Programming, 2013
Four columns of failures have accumulated: two bracket stacks (Chapter 10), the single-page application (Chapter 11), and the applet (Chapter 12). The pattern repeats. The scores cannot say where architectures that fail this way keep coming from. One observation can: they do not come from the web. Relational databases, object orientation, object-relational mappers (ORMs), imperative languages, and MVC (model–view–controller) all predate the web. Each fails the derived requirements at one identifiable seam, and that is why each drags a compensating industry behind it at the web boundary. The industries are the measurement: nobody builds a bridge across a gap that isn’t there. And the reading is falsifiable: a compensating industry that grows up around a paradigm failing no derived requirement — a market pricing a gap the audit cannot name — would break it.
Relational
The strongest of the pre-web paradigms, and the most instructive. Inside one database the model scores where nothing else pre-web does. Relational algebra is denotational — S2-grade semantics decades before the web. The query/storage separation is genuine S1 discipline. The failure is R3, and it is total: keys are database-scoped, so reference stops at the connection string, and two databases that never coordinated share no name for anything. R2 goes down with it: composition now requires a schema authority. The compensating industry is integration itself: every pair of silos bridged by hand, per pair, forever.
Object orientation
Encapsulation is the deliberate fusion of state and behavior. That is R1 half-inverted: state exists, but in order to be hidden. Objects are designed neither to merge nor to be referenced from outside their runtime; identity is a pointer. The compensating industries: serialization frameworks and data-transfer-object (DTO) layers — machinery for re-extracting the state the paradigm hid, every time it must travel.
ORM
An ORM is a type error between two wrong models: object graphs mapped onto relations, machine-local identity onto database-scoped keys. Each side fails a different requirement — R1 on the object side, R3 on the relational — and the mapping inherits both. The object-relational impedance-mismatch literature is its own measurement.
Imperative languages
S2 unreachable in principle — Chapter 11’s argument at the language level. The compensating machinery is the testing pyramid. When meaning is execution, every claim about meaning must be executed to be checked — semantics recovered empirically, per program, forever.
MVC
The paradigms above, assembled: a Model without R2 or R3, Views without S2, Controllers fusing what S1 separates. Take it apart and each part has a derived generic replacement. The model gives way to the shape of a fact (5.3), the view to ⟦t⟧ and ⟦s⟧, and the controller to read and write themselves — which HTTP had already provided.
| Paradigm | Fails | The compensating industry |
|---|---|---|
| Relational | R3 (keys are database-scoped) | integration: hand-built bridges between silos |
| OOP | R1 half-inverted (state present but hidden) | serialization frameworks, DTO layers |
| ORM | a type error between two wrong models | the impedance-mismatch literature |
| Imperative | S2 unreachable in principle | testing pyramids doing the work semantics should |
| MVC | all of the above, assembled | all of the above, assembled |
These are not outdated because they are old — HTTP is old. They are pre-web in the technical sense: their reference, composition, and semantics mechanisms are machine-local, and the web is definitionally the machine-spanning case. The 1960s–70s stack answers “how do I compute inside one machine”. The web asks “how do independent parties share state with no coordinator”. Theorem 5.4 shows the second question forces a model none of them is.
Two columns cover the five paradigms. OOP and its ORM share one. Imperative’s audit is a single cell — S2, unreachable in principle. MVC’s column would be the others, assembled.
| Relational | OOP/ORM | |
|---|---|---|
| R1 | ✓ — any domain, one schema at a time | ~ — state present but hidden |
| R2 | ✗ — no shared names, so composition needs a schema authority | ✗ — objects do not merge |
| R3 | ✗ — keys are database-scoped | ✗ — identity is a pointer |
| S1 | ✓ — query separated from storage | ✗ — encapsulation fuses state and behavior |
| S2 | ✓ — relational algebra is denotational | ✗ |
| S3 | ~ — within one vendor’s dialect | ~ — behind interfaces, within one runtime |
| S4 | ✗ — no value addressable from outside | ✗ |
Read the relational column twice: the highest pre-web score in the book, failing on exactly the machine-spanning properties. The diagnosis follows the scores — a correct answer to the single-machine question, put to the machine-spanning one. The scores are settled; the industry is not. It has spent a decade paying these costs; what it did in response is the next chapter.