Why this matters
In 1968 Edsger Dijkstra published "Go To Statement Considered Harmful," one of the most influential papers in computer science. He proved mathematically that programs built only from sequence (statements in order), selection (if/else), and iteration (loops) can be recursively decomposed and formally verified. Programs with unrestricted goto cannot.
Modern languages removed goto, but developers still write its spiritual equivalent: deeply nested conditions, boolean flags as control flow, and loops that simulate jumps. These patterns make functions impossible to test in isolation and impossible to reason about at a glance. The principle behind structured programming applies today: if a human must simulate the machine to read a function, the structure is fighting them.
The problem
A flag variable used to break out of a loop is a goto in disguise. Deep nesting makes the control flow impossible to follow without running the code mentally.
Bad
def find_first_even(numbers: list[int]) -> int | None:
found = False
result = None
index = 0
keep_going = True
while keep_going:
if index >= len(numbers):
keep_going = False
else:
if not found:
if numbers[index] % 2 == 0:
result = numbers[index]
found = True
keep_going = False
index += 1
return result
function findFirstEven(numbers: number[]): number | null {
let found = false;
let result: number | null = null;
let index = 0;
let keepGoing = true;
while (keepGoing) {
if (index >= numbers.length) {
keepGoing = false;
} else {
if (!found) {
if (numbers[index] % 2 === 0) {
result = numbers[index];
found = true;
keepGoing = false;
}
}
index++;
}
}
return result;
}
The solution
Sequence, selection, and early return — no flags, no nesting. The control flow is traceable in a single read from top to bottom.
Good
def find_first_even(numbers: list[int]) -> int | None:
for n in numbers:
if n % 2 == 0:
return n
return None
function findFirstEven(numbers: number[]): number | null {
for (const n of numbers) {
if (n % 2 === 0) return n;
}
return null;
}
Key takeaway
If a reader must simulate the machine to follow a function's control flow, the code is structured programming done wrong — regardless of whether goto appears in the source.