5 ms·
Thanks for sharing this. I had the same reaction. I have another point to add: many people think of “goto considered harmful” as saying something like: you can
by svat 7y ago
Thanks for sharing this. I had the same reaction. I have another point to add: many people think of “goto considered harmful” as saying something like: you can use all the other control structures that (say) C provides, but the “goto” statement should not appear in your program. At least that's what I thought, but in Knuth's encyclopedic response to the article, after giving some examples where eliminating goto (mechanically or otherwise) doesn't give great results, there's a section [1] where he discusses some proposed alternative control structures to goto — and among them is “break”! And on rereading Dijkstra's article and looking at the responses to it and some languages from the time, it dawned on me that what Dijkstra was advocating was that the only control structures be conditionals, loops, and subroutines — no “break” or “continue”, no early “return” in a function — and for example this (plus a discouraged goto) is in fact how things work in the original Pascal language (where you return from a function by assigning to a pseudo-variable and waiting for control flow to reach the end). Most programmers who echo “goto considered harmful” have not actually tried the discipline of giving up all of those and seeing how happy they are. Languages have realized that the barebones proposed by Dijkstra were inadequate and have added “break”, “continue” and “return” and even more control-flow structures, like exceptions.
The weak version of the thesis is that too much ad-hoc control flow can be confusing and is best avoided. But most programmers agreed with this anyway (there wouldn't have been much of a debate if this was all it was), and in this version there's no reason the limited set of control-flow structures cannot involve some use of the “goto” keyword (like the “goto end” / “goto cleanup” pattern in C code). The strong version of the thesis, as mentioned in the previous paragraph, is something no one really wants to live with (and I haven't seen the “coordinates” in practice either way). So what people seem to have settled on is an in-between version that abandons the actual content of Dijkstra's article, while retaining the word “goto” as a marker of sin.
[1]: http://www.kohala.com/start/papers.others/knuth.dec74.html#comparison http://www.kohala.com/start/papers.others/knuth.dec74.html#c...
- munificent 7y ago> And on rereading Dijkstra's article and looking at the responses to it and some languages from the time, it dawned on me that what Dijkstra was advocating was that the only control structures be conditionals, loops, and subroutines I'm actually not sure if that's what he's advocating. In fact, one of my main complaints with the letter is that he's really not very clear about what he's saying at all. Some of that may be just context that he could assume people had when he wrote it that has been lost since, but I think some of the blame rests on him. He does say: > One can regard and appreciate the clauses considered as bridling its use. I do not claim that the clauses mentioned are exhaustive in the sense that they will satisfy all needs, but whatever clauses are suggested (e.g. abortion clauses) they should satisfy the requirement that a programmer independent coordinate system can be maintained to describe the process in a helpful and manageable way. Which I interpret to mean that some goto-ish statements are fine if they are restricted in a way that doesn't make them hard to reason about. I think he would probably consider break, continue, and early returns acceptable in that way since he specifically mentions "abortion clauses", which sounds similar to those to me. But he never really defines what he considers an acceptable "briding", so we're still left in the dark.
- svat 7y agoThat's fair. From just the original article, it's hard to guess what Dijkstra's intent was or if he even had a clear idea himself. But if you look at the "goto debate" of the time -- the various letters published by various people pointing out "how would you do the following without goto?" as others had meanwhile started treating goto as sinful and avoiding goto with the moral zeal of new converts -- then it appears that regardless of Dijkstra's intention, at least the debate among most programmers at the time was about abandoning "goto" even in the absence of other compensating control structures. So it appears to me that the debate was settled, and eventually faded away into a catchphrase, not simply by everyone agreeing that goto is evil persuaded by Dijkstra's arguments, as the popular opinion holds, but by languages adding most of the control structures that people were using "goto" for, under different names, until ad-hoc "goto" became less and less necessary. (And even Dijkstra's response to those responses, namely, his "On a somewhat disappointing correspondence" (original: http://www.cs.utexas.edu/users/EWD/ewd10xx/EWD1009.PDF http://www.cs.utexas.edu/users/EWD/ewd10xx/EWD1009.PDF / transcript: https://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1009.html https://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/E...), which incidentally is a good example of why they used to say that arrogance is measured in nano-Dijkstras, reveals that for example he was against short-circuiting AND/OR ("conditional connectives"), that he wrote his loops with boolean variables checked in the loop condition rather than break, and that he wrote of "all sorts of “programming language features” that seem better ignored than exploited" -- so in the original when he writes that "whatever clauses are suggested (e.g. abortion clauses) they should satisfy the requirement..." it's not clear that break/continue would satisfy his requirement because it's never specified, as you say.) And as you say, it's not clear that it was an improvement as far as language research goes, because it's far from obvious that the set we've settled on is the most natural or useful one: C has while, do-while, and for, each with break and continue, but alternatives like repeat-until (expressible as do {...} while(!(...));) were contenders, and especially Zahn's "event indicators" system looks quite nice (http://www.kohala.com/start/papers.others/knuth.dec74.html#event http://www.kohala.com/start/papers.others/knuth.dec74.html#e...). (I guess in Python it's not unusual to do something similar using exceptions, so they've returned in some form.)
- munificent 7y ago