Go To Statement Considered Harmful is remembered as goto is evil, but what defect in jump-ridden control flow did it actually name?
answer
- about reasoning, not style
- static text versus running process
- describing progress with few coordinates
- a label reachable from anywhere
- every predecessor must satisfy the assertion
basics
~20 sThe objection was about reasoning, not taste. With unrestricted jumps you can no longer describe where a running program has got to using a few coordinates, so a position in the text stops telling you what already happened.
solid answer
~50 sThe argument is about the gap between the text you read and the process it produces. In code built from sequence, selection and iteration, a reader can pin down where execution has reached with a small set of coordinates: a position in the text, a counter for each loop currently running, and the chain of active calls. Each of those is something a person can name and hold in mind. An unrestricted jump breaks that correspondence, because any label can be reached from anywhere: `we are at the retry label` no longer tells you which of nine predecessors sent control there or what held on the way. The practical consequence is that any assertion you attach to a label must hold for every predecessor, so the cost of justifying it grows with the number of jump sites rather than with the size of the routine.
go deeper
Recall the shape of the claim: jumps make it hard to tell what has already happened when you look at a line of code. You are not expected to reconstruct the historical argument.
Be able to explain the mechanism: structured constructs let a reader describe progress with a few coordinates, and an arbitrary jump gives a target an open set of predecessors. Say what that costs a reader.
Show you can apply the cost model rather than the slogan. Point at code where the jump is cheap and at code where a flag or a distant write has the same defect without the keyword.
The angle here is what you standardise on. A keyword ban is easy to enforce and misses the defect; a rule phrased in terms of predecessors and direction is harder to automate but actually targets what costs the reader.
## The claim the letter actually made A program is static text; running it produces a dynamic process. The whole job of reading code is bridging those two — given a point in the text, say what the process has already done and what must be true there. The 1968 letter **Go To Statement Considered Harmful** is an argument about that bridge, and its case is narrow and specific: in code assembled from **sequence, selection and iteration**, a reader can describe where a process has got to with a **small set of coordinates**. A position in the text. One counter per loop currently running. The chain of calls currently active. Every one of those is nameable, finite, and meaningful to a human. An unrestricted jump destroys that correspondence. When any label may be reached from any point, a position in the text no longer implies a history. Standing at a label called `retry` tells you nothing about which of its predecessors sent control there, which variables were assigned on the way, or how many times this has already happened. To describe the process state you now need the position **plus the path taken to it**, and the number of paths grows with the number of jump sites rather than with the length of the routine. ## Coordinates, concretely - **Sequence** gives an index: everything above this point has run, everything below has not. - **Selection** gives a branch identity: exactly one arm ran, and the condition that chose it is written next to it. - **Iteration** gives a counter plus a property that holds on every entry to the body, so partial progress is describable. - A **call** gives a frame: the caller is suspended and control returns to the point just after the call. - An **arbitrary jump** gives none of these. Its target has an open set of predecessors, and the reader must scan the whole routine to enumerate them. ## Reasoning, not aesthetics The consequence the letter cares about is the ability to state something at a point and defend it. An assertion attached to a label must hold for **every** predecessor that can reach that label. With three jump sites you discharge three obligations; with thirty you discharge thirty, and the text gives you no help finding them. That is why the argument is usually restated as a claim about **provability**: jump-ridden code does not become wrong, it becomes expensive to argue about — and code nobody can argue about is code nobody can safely change. ## The folk version and what it drops | The slogan | What the argument says | |---|---| | goto is evil | Unrestricted jumps break the match between text and running process | | never write a jump | Some jump shapes preserve single entry and stay defensible | | it is a style preference | It is a claim about how cheaply a point can be reasoned about | | jumps are slow | The cost falls on the reader and the prover, not on the machine | The slogan is not a quotation; it is a compression, and compressing an argument about reasoning into a rule about a keyword is what produces the two failure modes you still see. One team bans the keyword and accepts anything that avoids it, including a failure flag threaded through every later step, which reproduces the same non-local coupling with the arrow made invisible. Another team dismisses the whole thing as dogma because the slogan is obviously too strong. ## What the argument does not claim 1. It does not rank all jumps equally. A forward jump to one label near the end of a short routine costs a reader far less than a jump that lands inside a block, and the argument's force scales with how far the jump moves and how many predecessors a target collects. 2. It does not claim a performance defect. Nothing in it is about instruction cost. 3. It does not, on its own, establish that the three structured forms are **sufficient** to express every program. That sufficiency is a separate result with a separate subject; the letter is about what a reader and a prover can afford. ## Why interviewers still ask it The question separates a candidate who carries a slogan from one who carries a mechanism. The first says jumps are bad practice and stops. The second can say what a jump costs — an unbounded predecessor set at every target — and therefore knows when a jump is cheap, which is exactly the judgment needed when a routine has to unwind partially acquired resources or dispatch on a state. The mechanism also transfers: the same argument explains why a mutable flag read at a distance, or a callback that resumes control somewhere unrelated, is hard to reason about for precisely the same reason.
- Why does the argument target the jump and not the loop, which also sends control backwards?A loop has one entry and one exit, and the backward transfer is written into the construct itself, so the set of predecessors of the body is fixed and visible. That lets a reader attach one property that holds on every entry, plus a counter for progress. A bare backward jump has neither: its target collects predecessors from anywhere in the routine.
- Does the same objection apply to a single forward jump inside one short routine?Far more weakly. A forward-only jump to one label keeps the ordering of regions and adds exactly one predecessor to one target, so the reader's extra obligation is small and local. The strong form of the objection is about jumps that land inside a block or that send control backwards to form an ad-hoc loop.
- What does the argument say about a mutable variable read far from where it is written?The same thing, in different clothes. The cost named is that the state at a point depends on history you cannot see from the text, and a distant write is exactly that. This is why replacing a jump with a flag threaded through later steps does not pay the debt; it redistributes it.
Structured code reads like a recipe with numbered steps and a stated repeat-until: knowing which step you are on tells you what is already in the bowl. Jump-ridden code reads like a recipe where any line may say now go to line twelve, so the line number tells you nothing about the bowl.
saying these in an interview costs you the question
- Claims the letter demanded the jump be removed from every language
- Says jumps are harmful because they run slower than conditionals
- Treats goto is evil as the argument itself rather than a later slogan
- Reduces it to readability with nothing about arguing correctness
- Claims every jump is equally harmful regardless of direction or target
- Thinks the objection is settled by banning one keyword