Go To Statement not that Harmful

You might have heard that the goto statement is considered harmful, and it’s certainly very possible to write spaghetti code using goto, but is there any nuance, is a blanket ban really necessary? Is a letter written in 1968 to academics writing code to be analysed by other academics, by an author who can’t possibly have conceived of a world where everyone has a cheap computer for hobby coding, still totally relevant to today?

There’s a thing in secondary school teaching where students will defend their primary school teacher, and if you contradict them in secondary school, they will get very upset, because their teacher told them that, and it’s true, and it’s the only way of doing it.

– Matt Parker, A Problem Squared, e038, 2022.

Stepping stone for beginners just getting started

if and goto are all the control statements a programming language needs to be Turing complete. Both of these statements are much more intuitive to a beginner than learning about loops and scope and call stacks. Providing beginners with the minimum possible tools they need to get started and produce something means they are seeing results from the effort they are putting in much more quickly than if they have to learn enough structured programming to get to the same position. If that means they stay motivated and continue to learn then that’s surely a good thing.

But didn’t Dijkstra say something about goto producing bad programmers? Won’t teaching them about goto forever poison their brain and make it unable to reason about code without using goto? Let’s see:

For a number of years I have been familiar with the observation that the quality of programmers is a decreasing function of the density of go to statements in the programs they produce.

Note that this says nothing of the causation. goto doesn’t create bad programmers. Bad programmers use goto to fill the gaps in their knowledge. Taking away their gotos won’t magically make them better programmers. They will instead either (a) write bad code without goto, or (b) give up. This correlation instead suggests that as the ability of a beginner improves, their use of goto will naturally decline, which is what we have observed in the real world in the decades since Dijkstra’s letter. The generation of programmers who cite learning to program in BASIC in their bedroom in the 80s aren’t a cohort of terrible programmers forever incapable of writing structured code having written too many 20 GOTO 10s. On the other hand, who knows how many budding programmers were told to skip goto and go straight to structured programming only to find the learning curve too steep and give up.

Assembly langauge

What happens when you run a compiler on your beautiful goto-free code? It gets converted down into machine code (or possibly an intermediate byte code). But machine code doesn’t have any concept of structured programming. The only available instructions are some variation on the jump instruction jmp (equivalent to goto), conditional jumps (equivalent to if (condition) goto), and call, which is similar to method calls but everything stays in the global scope, so more akin to the old BASIC GOSUB statement. So the compiler is taking your code and essentially rewriting it with all the structure taken out and replaced by gotos.

This creates situations where being able to write clear code using goto or equivalent is not only useful, but necessary:

Dijkstra even conceded that these were acceptable uses of goto.

Complex break conditions

The classic case for goto in a structured language is to break out of nested loops:

for ...
  for ...
    if(breakout_condition)
      goto final;

clean_up();

final:

You couldn’t refactor out the goto without re-checking the breakout_condition multiple times (either direct or via a flag), thereby making the refactored code more cluttered than the goto version. Dijkstra’s letter was making the case that goto makes code harder to reason about, so if you’re making the code harder to reason about by avoiding goto then you’re missing the point.