News for hackers. Stuff that matters.
Re:GOTOphobia Considered Harmful (In C) by jjav on Sunday February 26, 2023 @03:51PM (#34949275)
> The thing is that many people today have never encountered the sort of spaghetti code that Dijkstra was talking about in 1968.

Can't highlight this enough. The type of spaghetti code "goto considered harmful" was reacting to is basically impossible to create anymore, so anyone who didn't work on that type of code in the 80s or earlier probably hasn't seen it.

And thus, is applying the mantra "goto considered harmful" incorrectly. (Such as trying to avoid it in C for clean error handling, when there's no reason to avoid that.)

To try to replicate that experience, you'd have to write your entire application (including all libraries since libraries were often not a thing) as one single function in C. All of it, no matter how many tens of thousands of lines of code, all in one function. Then label every line. Then picture having GOTOs going every which way to any of the labels. For instance you'd preset the counter variable to some desired value and jump right into the middle of a loop elsewhere. Over time you'd surely accumulate special conditions within that loop to jump out. And so on. It's difficult to even imagine code like this today (or in the past 30 years).

Re:GOTOphobia Considered Harmful (In C) by piva00 on Sunday February 26, 2023 @04:27PM (#34949656)
I agree, the closest modern equivalent is code that branches too much from too many places. Modern tools still help a lot to reason about it but it comes to a place where I, personally, have to create call flow diagrams on pen and paper or a whiteboard to actually understand some flows.

Code with extreme branching, while dealing with state/boolean parameters that determine flow branching; error handling that can also create other branches of execution; all of that is really hard to keep in mind when reading such nightmare codebases...

Re:GOTOphobia Considered Harmful (In C) by strangattractor on Sunday February 26, 2023 @04:53PM (#34949917)
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.

Re:GOTOphobia Considered Harmful (In C) by lolinder on Sunday February 26, 2023 @05:03PM (#34950006)
CONTINUE 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.

Re:GOTOphobia Considered Harmful (In C) by JohnBooty on Sunday February 26, 2023 @05:20PM (#34950190)
Not 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.

Re:GOTOphobia Considered Harmful (In C) by bdowling on Monday February 27, 2023 @02:19AM (#34953927)
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.
Re:GOTOphobia Considered Harmful (In C) by staunton on Monday February 27, 2023 @02:43AM (#34954026)
Yes, 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.
Re:GOTOphobia Considered Harmful (In C) by bdowling on Monday February 27, 2023 @05:36AM (#34954905)
My 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.

Re:GOTOphobia Considered Harmful (In C) by UncleMeat on Monday February 27, 2023 @08:44AM (#34956292)
IF 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.

Re:GOTOphobia Considered Harmful (In C) by lolinder on Monday February 27, 2023 @09:57AM (#34957129)
My 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.

Re:GOTOphobia Considered Harmful (In C) by bdowling on Monday February 27, 2023 @03:59PM (#34961770)
> 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).

Re:GOTOphobia Considered Harmful (In C) by lolinder on Monday February 27, 2023 @04:17PM (#34961969)
No, 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.

Re:GOTOphobia Considered Harmful (In C) by strangattractor on Tuesday February 28, 2023 @02:16PM (#34973519)
The 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:)
Re:GOTOphobia Considered Harmful (In C) by int_19h on Monday February 27, 2023 @04:40AM (#34954607)
Structured 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.

Re:GOTOphobia Considered Harmful (In C) by lolinder on Monday February 27, 2023 @10:08AM (#34957260)
They'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).

Re:GOTOphobia Considered Harmful (In C) by bdowling on Monday February 27, 2023 @04:13PM (#34961929)
See 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.

Re:GOTOphobia Considered Harmful (In C) by lolinder on Monday February 27, 2023 @04:23PM (#34962047)
No, 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.

Re:GOTOphobia Considered Harmful (In C) by bdowling on Monday February 27, 2023 @05:42PM (#34963040)
We apparently disagree on whether the general, flexible construct is the subtype or whether the specific, constrained construct is the subtype. You seem to be thinking from a object-oriented programming class hierarchy perspective, while I am thinking from a set theory perspective (i.e, the set of operations that can be done with GOTO is a superset of those that can be done with CONTINUE or BREAK).

At this point, I don't care which you call the subtype. You can claim that as a win if you want, but having spent so much time on this stupid thread I think we've both lost.

Re:GOTOphobia Considered Harmful (In C) by lolinder on Monday February 27, 2023 @06:07PM (#34963302)
I actually rather enjoyed the conversation and didn't feel it was wasted at all, but I'm sorry you didn't feel the same. I wasn't in it to win, just to explore the idea.

I'm still interested in exploring the idea, but you're welcome to tune out at any point.

> the set of operations that can be done with GOTO is a superset of those that can be done with CONTINUE or BREAK

Yes! And this is actually part of my point. If Y is a subtype of X, then the set of valid operations on Y is a superset of the set of valid operations on X. This is true for any types, by the definition of subtyping.

This means that you're absolutely correct that the set of operations GOTO can perform is a superset of those BREAK can perform, and for this very reason GOTO is a subtype of BREAK.

The reason why I'm focused on the types and not the operations is because the question at hand has been whether BREAK has the same flaws as GOTO. My argument is that this hinges on whether or not BREAK is just a type of GOTO.

Re:GOTOphobia Considered Harmful (In C) by bazoom42 on Sunday February 26, 2023 @05:15PM (#34950142)
The 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.

Re:GOTOphobia Considered Harmful (In C) by Gibbon1 on Sunday February 26, 2023 @08:30PM (#34951890)
Far 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.
Re:GOTOphobia Considered Harmful (In C) by Jtsummers on Sunday February 26, 2023 @08:46PM (#34951980)
If 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_T...

Re:GOTOphobia Considered Harmful (In C) by bdowling on Monday February 27, 2023 @02:08AM (#34953874)
> 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.

Re:GOTOphobia Considered Harmful (In C) by josefx on Monday February 27, 2023 @02:32AM (#34953970)
> 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?

Re:GOTOphobia Considered Harmful (In C) by lolinder on Monday February 27, 2023 @10:00AM (#34957172)
Predictably 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.
Re:GOTOphobia Considered Harmful (In C) by nullc on Monday February 27, 2023 @01:46AM (#34953776)
A 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.
Re:GOTOphobia Considered Harmful (In C) by RustyRussell on Monday February 27, 2023 @01:38PM (#34960199)
Generally 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.
Re:GOTOphobia Considered Harmful (In C) by nullc on Monday February 27, 2023 @08:52PM (#34964696)
I'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.]

Re:GOTOphobia Considered Harmful (In C) by snovv_crash on Sunday February 26, 2023 @05:20PM (#34950192)
Sure it's possible to have horrible spaghetti today. Just look at any pubsub architecture based system and tell me what piece of code executes after another. It's super popular, and it's GOTOs all over again, just with data instead.
Re:GOTOphobia Considered Harmful (In C) by jjav on Monday February 27, 2023 @02:50AM (#34954067)
This is a good observation, thanks. Yes, some of these cloud-native patterns do become what is essentially a spaghetti flow pattern, even if not in the fragmented pieces of code directly.
Re:GOTOphobia Considered Harmful (In C) by zozbot234 on Monday February 27, 2023 @03:10AM (#34954172)
Async-await in general has all the same pitfalls. In fact, async programming, being based on reifying program continuations, is a GOTO equivalent in a quite literal sense.
Re:GOTOphobia Considered Harmful (In C) by snovv_crash on Monday February 27, 2023 @08:03AM (#34955912)
It's not just cloud, ROS uses this for robotics, for example.
Re:GOTOphobia Considered Harmful (In C) by emodendroket on Sunday February 26, 2023 @11:24PM (#34952936)
Technically nobody stops you from writing one giant function with labels and goto, it's just not the most obvious path even to the most inexperienced programmers.
Re:GOTOphobia Considered Harmful (In C) by josephg on Monday February 27, 2023 @12:34AM (#34953383)
> The type of spaghetti code "goto considered harmful" was reacting to is basically impossible to create anymore, so anyone who didn't work on that type of code in the 80s or earlier probably hasn't seen it.

Its still quite possible in assembly, where goto (JMP) is your only way to do control flow. But I doubt there's many people left who write and maintain large assembly programs. I imagine most programmers reach for C or something higher level as soon as the program becomes non-trivial.

I still use this cute online Intel 4004 simulator sometimes when I teach programming:

http://e4004.szyc.org/

Its a fun challenge for novice or advanced programmers alike to write little programs in assembly for a CPU from 1971. The assembly language[1] is only 45 commands, and you only need a handful of them anyway. The CPU interpreter is simple enough you can literally see it think.

[1] http://e4004.szyc.org/iset.html

Re:GOTOphobia Considered Harmful (In C) by jjav on Monday February 27, 2023 @02:53AM (#34954080)
> Its still quite possible in assembly, where goto (JMP) is your only way to do control flow.

Yes, certainly very possible in assembly as it ever was. But as you note, few people are doing large scale assembly programs anymore. And I'd say that those who still do, are sufficiently experienced to avoid unstructured jump explosion in their code, hopefully.

Re:GOTOphobia Considered Harmful (In C) by bazoom42 on Monday February 27, 2023 @03:07AM (#34954158)
> Such as trying to avoid it in C for clean error handling, when there's no reason to avoid that.

Dijkstra would clearly disaprove of this use of goto. Buy he would blame the C language for making it necessary. Languages with structured cleanup (like the using clause in C#) does not need to use gotos for resource cleanup.

Dijkstras argument does not distinguish between short and long gotos or long or short functions. His argument applies to any use of goto.

Re:GOTOphobia Considered Harmful (In C) by hegzploit on Monday February 27, 2023 @03:34AM (#34954283)
Where would once find examples of such code?
Re:GOTOphobia Considered Harmful (In C) by vasirian on Tuesday February 28, 2023 @08:13AM (#34968879)
Among others, likely in old introductory books on BASIC or its other flavors.
Re:GOTOphobia Considered Harmful (In C) by zappchance on Wednesday March 01, 2023 @03:11PM (#34987611)
A modern example of code like this would be any game coded in SmileBASIC for the 3DS.
Re:GOTOphobia Considered Harmful (In C) by int_19h on Monday February 27, 2023 @03:44AM (#34954335)
I learned coding in the 90s and I've seen that kind of code. While BASIC itself already advanced to the point where structured conditionals and loops were available pretty much everywhere, plenty of code that was written earlier was still around.