5 ms·
CONTINUE 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 off
by bdowling 4y ago
CONTINUE 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.
- lolinder 4y agoMy point is that it's meaningless to make the argument that CONTINUE and BREAK can be implemented with GOTO, because every control flow structure can be. That you could use a GOTO to implement them isn't in question, what's in question is if you could do the reverse. It's a subtyping problem, and you have the is-a relationship backwards: a cat is an animal but not every animal is a cat. GOTO is a BREAK (could always be substituted for one), but a BREAK is not a GOTO. When you need a BREAK you could implement that in terms of GOTO, but no amount of coercion will allow you to use a BREAK as a generic GOTO.
- bdowling 4y ago> GOTO is a BREAK (could always be substituted for one), but a BREAK is not a GOTO. You wrote this backwards, but you seem to understand the relationship and that GOTO is more general. That is, every BREAK is a GOTO (because you can always substitute a GOTO), but every GOTO is not a BREAK (i.e., you can't substitute a BREAK for some GOTOs because BREAK cannot jump to an arbitrary label).
- lolinder 4y agoNo, I wrote it in exactly the order I wanted to. Because of the substitution property that you acknowledge, GOTO is a subtype of BREAK. BREAK is not a subtype of GOTO because it cannot always be substituted for GOTO. Thus, "GOTO is a BREAK, but a BREAK is not a GOTO." A GOTO is just one possible implementation of BREAK, just as a cat is one possible implementation of an animal. The practical impact of this is that it is incorrect to ascribe to BREAK the same weaknesses as GOTO, because BREAK is not a GOTO.
- strangattractor 4y agoThe moment I received a down vote for a simple opinion/observation about relieving naming overload and the similarities of BREAK and CONTINUE to GOTO I knew where this was going:)
- int_19h 4y agoStructured if/then/else is also merely syntactic sugar over if/goto, but that doesn't make it any less useful. What makes break/continue (including labelled variants a la Java) useful is the fact that the restriction on where they can jump means that the control flow graph is guaranteed to be reducible. That is not the case with free-form goto.
- lolinder 4y agoThey're not syntactic sugar in any language that does not have GOTO, because the semantics of GOTO-free languages don't allow arbitrary jumps, so there is no equivalent syntactic structure that you can compile BREAK to. The distinction matters because the whole premise of Dijkstra's argument is that if you replace the GOTO keyword with a bunch of more limited versions that cannot be used to produce spaghetti, code quality would go up. The only way for that to work is for the language to be semantically incapable of expressing GOTO. As I said in my other reply, you seem to have the subtyping relationship wrong: GOTO is a subtype of BREAK (anywhere you find a BREAK you could replace it with GOTO), but BREAK is not a GOTO (you cannot do the reverse).
- bdowling 4y agoSee my other reply. GOTO is the generic type because it can be used to jump anywhere. BREAK/CONTINUE are sub-types because they are limited in where they can jump. BREAK/CONTINUE can be always implemented using GOTO, but not the other way around. I agree that BREAK/CONTINUE are not syntactic sugar in languages that don't have GOTO.
- lolinder 4y agoNo, you're still mixing up the subtype relationship. Type X is a subtype of type Y if and only if an instance of X can always be used where an instance of Y is required. GOTO can always be used to replace a BREAK. Therefore GOTO is a subtype of BREAK. BREAK cannot always be used to replace a GOTO. Therefore BREAK is not a subtype of GOTO. The inheritance relationship here is not single, it's multiple: a GOTO is a BREAK, but it is also a CONTINUE and a whole lot of other things. It's like a monster class that inherits from every interface under the sun and can do just about anything. Dijkstra was basically advocating for refactoring our languages to extract those capabilities into smaller, more focused keywords (as well as dropping most of the functionality). Rather than having one keyword implement both the BREAK and CONTINUE interfaces, we break them out into separate keywords.
- bdowling 4y ago