3 ms·
Have you read Knuth’s article? It is a bit more nuanced than a wholesale defence of GOTO in preference to structured programming. It surveys various control f
by pwdisswordfish8 5y ago
Have you read Knuth’s article? It is a bit more nuanced than a wholesale defence of GOTO in preference to structured programming. It surveys various control flow structures that are not easily expressed in terms of IF conditions and WHILE loops (what structured programming advocates of the time argued to replace GOTO with), but more easily expressed with GOTO, and it argues that, since we don’t know which of those constructs will ultimately end up the most useful, it might be prudent to keep GOTO around, at least for a while, and not confine ourselves to simple conditionals and loops just yet. But if we do find better structured control-flow primitives, perhaps we may get rid of GOTO after all. The comments under the Torvalds link kind of point it out already: GOTO is used in the Linux kernel as a crutch for the deficiencies of C, like the lack of scope-based destructors, exceptions and the ability to specify which loop a BREAK statement targets.
My favourite part of the Knuth paper is this:
begin until error or normal end:
if m = max then error ('symbol table full') fi;
normal end;
end;
then
error (string E) =>
print ('unrecoverable error,'; E);
normal end =>
print ('computation complete');
fi;
This is pattern-matching on a Result<(), String>, in 1974. How adorable!
It’s a shame that innovation in this area has stagnated so much: most languages only feature IF, WHILE, FOR, single-level CONTINUE/BREAK, SWITCH (with fallthrough), and GOTO as an escape hatch in case the others are insufficient, just because they are so familiar. Only now languages like Python or Java are getting any form of pattern matching. Though props to the latter for at least allowing to break multiple loops by way of labelling the outermost one.
- andi999 5y agoYes, I read it and I agree with your text. My point was just that goto is not evil, sometimes it is your best option (like in the parent if loops do not have break). On a side one could argue that early returns, while often used, are not structured programming and a goto in disguise.
- Joker_vD 5y agoWell, it's slightly more powerful that pattern-matching Result because in case of nested loops you can short-circuit right to the very top loop. Writing corresponding nested maps/folds is generally quite unsightly. Plus the resulting code may be non-tail-recursive which means that the sentinel EarlyExit value will get checked and re-returned for every function in the call stack on such exit. This loop construct, however, basically introduces locally scoped continuations that you can directly return to. Of course, it's possible to optimize nested maps/folds down to this form, but it requires very heavy inlining — Haskell does it because it's semantics allow deforestation, but does Rust do it?