Skip to main content
Clean Architecture 60 XP · 6 min

Structured Programming: Discipline over Direct Control

Dijkstra proved unrestricted goto is harmful. Sequence, selection, and iteration alone are sufficient for correct, decomposable modules.

Showing
Ad (728×90)

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.

Done with this lesson?

Mark it complete to earn XP and track your progress.