7 ms·
If you have ever seen someone try an construct a bunch of nested IF statements with complicated conditional clauses you might think GOTO is not so bad. People
by strangattractor 4y ago
If you have ever seen someone try an construct a bunch of nested IF statements with complicated conditional clauses you might think GOTO is not so bad. People have simply become better coders. There are also still GOTOs that are used in specific cases such as CONTINUE and BREAK - no labels required.
If I look back it always comes back to naming and managing names of things. GOTO 100 is meaningless and one eventually runs out of meaningful names for GOTO labels. For me OOPs addressed the naming issue relatively effectively by using the data type as a namespace of sorts.
- lolinder 4y agoCONTINUE and BREAK are quite different from GOTO in that they operate predictably given the current scope: their limitations make them incapable of creating the unstructured nightmare that Dijkstra was talking about. They're similar to a GOTO only in that they compile to a jump, but so do IF statements and FOR loops. Structured programming wasn't about eliminating jumps, it was about enforcing discipline in their use. The simplest way to do that is to eliminate raw GOTO from the language, but it's also possible to just be careful and use it wisely.
- bazoom42 4y agoThe argument against gotos in Dijkstras article would apply equally to breaks and continue and even to early returns. I dont fully agree with Dijkstras argument. For example I think early returns can often improve the readability of the code. But worth noting Dijkstra is not primarily concerned about readability but rather about how to analyze the execution of a program.
- Gibbon1 4y agoFar as I could tell coming in on the end of it people like Dijkstra were primary trying to write proofs about programs. That motivated them to ban constructs they didn't know how to analyze. Problem is that some of those things turned out to be trivially tractable but lots of people never got the memo.
- Jtsummers 4y agoIf you read Dijkstra's letter it wasn't about formal proofs. It was about go to statements being very hard to reason about, especially when trying to understand the flow of a program and how you got to a particular point in its execution. The word "proof" doesn't even show up in the letter. It's only a page or so, well worth a read instead of guessing at what he may have been writing about. http://www.u.arizona.edu/~rubinson/copyright_violations/Go_To_Considered_Harmful.html http://www.u.arizona.edu/~rubinson/copyright_violations/Go_T...
- JohnBooty 4y agoNot too many things make me shake my head harder than folks who consider continue/break to be GOTO equivalents. For the reasons you eloquently said. Additionally, far more often than not, continue/break allow you to avoid another form of complexity, bugs, and low comprehensibility: deeply nested conditionals.
- bdowling 4y agoCONTINUE and BREAK are simply jumps to the beginning of or just past the end of the current loop context. They are equivalent to GOTOs to particular program offsets without the programmer needing to create labels for those offsets. They do not have any magical meaning beyond that. You could even call them syntactic sugar.
- staunton 4y agoYes, it's all compiled to jumps... The point of the discussion is that things like continue and break are easier to read and reason about because they can't just jump anywhere.
- bdowling 4y agoMy point was to contest GP's assertion that CONTINUE and BREAK were not equivalent to GOTOs. I agree that CONTINUE and BREAK are easier to reason about because you can look at them and instantly know what they do without having to look up what label they're jumping to.
- UncleMeat 4y agoIF and WHILE are also equivalent to GOTOs in that sense. The point is that CONTINUE and BREAK jump to exactly one location given their lexical context and cannot jump anywhere else. They are also only meaningful when applied to structured control flow. The problem with GOTO is the unbound nature of its jump target, which leads to control flow that is difficult to comprehend by looking at the lexical structure of a function.
- 4y ago
- bdowling 4y ago> CONTINUE and BREAK are quite different from GOTO in that they operate predictably given the current scope CONTINUE, BREAK, and GOTO all operate predictably because they are deterministic operations. Each continues program execution at the directed explicit (goto) or implicit (continue or break) offset. There is no non-deterministic or unpredictable behavior whatsoever.
- josefx 4y ago> operate predictably because they are deterministic operations If I sat you in front of a computer generating numbers using a pseudo random number generator and gave you as context the last number it generated, could you make any prediction about the next number it generates? Now if it used a prng that was known and standardized to only compute one number could you predict anything about the next number now?
- deleted 4y ago[deleted]
- lolinder 4y agoPredictably may have been the wrong word, because that does imply non-determinism. It might be better to say that CONTINUE and BREAK are limited: given a scope, the keyword can take you to exactly one place, while GOTO could be used to take you anywhere, and you have to go hunting for the corresponding label to find that place.
- nullc 4y agoA better rule than goto harmful is gotos should only go lower in the function and should only exit blocks and/or skip over them, never be used to enter them.
- RustyRussell 4y agoGenerally true, but I've been known to do `goto again;` for those cases where retrying is a corner case. Sure, you can put the entire code inside a `for(;;)` but if it almost always only runs once, you're not helping the reader understand the code.
- nullc 4y agoI'm fond of the MISRA C approach where you have all these bright line (even machine checkable maxims) but if you have a reason to break one you're just supposed to write up a report why its better to do it this way and how you've addressed the risks. Seems like a reasonable trade for the occasional "goto again". [Before anyone reads the above as advocating MISRA C ---- I think MISRA actually tells you not to do "goto fail;" which is advice I'm kind of dubious about. It also tells you to not do "good = good && side_effecty_thing();" (no shortcutting operators when there are side effects) so its style has you make a typical function absolutely littered with explicit initialization guards.]