Keyboard Navigation
W
A
S
D
or arrow keys · M for map · Q to exit
← Back to exhibits
Complexity & PerformanceCode FlawEXP-020

The Tangled Goto

When control flow became a maze with no map

1960s · FORTRAN / COBOL · 6 min read
Pattern Classification
Class
Complexity Accretion
Sub-pattern
Sedimentary Code
Invariant

Systems do not become complex. They accumulate complexity — one reasonable decision at a time — until no single person can hold the whole in their head.

This Instance

Dead code, unreachable branches, and obsolete paths accumulate as geological layers

Detection Heuristic

If understanding a single change requires understanding the entire system — if a class handles responsibilities that span multiple domains — if code exists that no one can explain but no one dares remove — complexity has accreted past the point of comprehension.

Same Pattern Class
Why It Persists

Every codebase experiences this. The force driving accretion is time itself — combined with changing requirements, changing teams, and the economics of "just add it here." Refactoring is expensive. Accretion is free. Until it isn't.

Pattern Connections
Precursor
The God Object

GOTO spaghetti (1960s) evolved into God Objects (1980s). The mechanism changed from unstructured control flow to unstructured responsibility, but the result is the same: systems too complex to comprehend

Enables
The Dead Branch

GOTO-heavy code accumulates unreachable branches because no one can trace the control flow well enough to identify what's dead

Year

1957–1968

Context

In the first decade of high-level programming, there was one control flow primitive: GOTO. FORTRAN (1957) had GOTO, computed GOTO, and assigned GOTO. COBOL had GO TO and ALTER (which changed where a GO TO pointed at runtime). Assembly, of course, had only jumps. Every program was a graph of numbered statements connected by explicit jumps. There were no if/else blocks, no while loops, no functions that returned to their caller by contract. There was GOTO.

Who Built This

Everyone. GOTO was not a bad practice adopted by lazy programmers. It was the only mechanism available. The languages provided GOTO because the hardware provided jumps. The abstraction matched the machine. Writing a sorting algorithm in FORTRAN II meant writing a sequence of numbered statements with GOTO instructions connecting them. The resulting control flow graph — if anyone had drawn it — would have looked like a plate of spaghetti.

Threat Model at Time

Correctness. Programs needed to produce the right output. The concern was not maintainability — programs were short, teams were small, and the programmer who wrote it was usually the programmer who maintained it. The idea that code needed to be readable by someone other than its author was years away.

Why It Made Sense

GOTO was efficient. It mapped directly to machine instructions. It was flexible — any control flow pattern could be expressed with GOTO. It required no runtime overhead. And it was the only tool available. Dijkstra himself used GOTO extensively in his early work. The problem was not that GOTO existed. The problem was that nothing else did.

Archaeologist's Note

This pattern has been found in applications built by talented developers at respected organizations across every decade of software history. Its presence in a codebase is not a reflection of the developer who wrote it — it is a reflection of what that developer was taught, what tools they had, and the path that was easiest given what they were taught. The goal is not to find fault. The goal is to find the pattern — before it finds you.

Katie's Law: The developers were not wrong. The shortcut was not wrong. The context changed and the shortcut didn't.

The FoundationThe Spaghetti Archives8 / 11
Previous ExhibitMuseum MapNext Exhibit