News for hackers. Stuff that matters.
Re:GOTOphobia Considered Harmful (In C) by ufo on Sunday February 26, 2023 @02:03PM (#34948301)
I always encourage people to go read Dijkstra's GOTO paper, instead of just its title. It's a short and easy read, almost like a blog post. If you pay attention, you can see that the he was talking about spaghetti code vs structured code. It's better when the lexical structure of the source code maps to the execution structure. That is, if you know what is the current line being executed, you have a good idea of what the global state is, which lines executed before this one, and which will be executed next.
Re:GOTOphobia Considered Harmful (In C) by arp242 on Sunday February 26, 2023 @02:53PM (#34948733)
The thing is that many people today have never encountered the sort of spaghetti code that Dijkstra was talking about in 1968. There's plenty of confusing and messy code around, but true spaghetti code that GOTOs all over the place and is nigh-impossible to follow has been extremely rare for a long time. I can't recall encountering it in the last 30 years.

It easy to misunderstand what he was even talking about because the paper is so short, assumes you know about this context, and has no concrete examples. People quite reasonably assume it's about ugly code they've encountered, but it's actually about ugly code of a completely different kind.

I'm not that old, but I was unlucky enough to have programmed in an unstructured language where GOTO was the only way to use faux-subroutines in my teens. Whatever you think as code that's difficult to follow: it's nothing compared to this.

Re:GOTOphobia Considered Harmful (In C) by spacechild1 on Sunday February 26, 2023 @03:30PM (#34949057)
> but true spaghetti code that GOTOs all over the place and is nigh-impossible to follow has been extremely rare for a long time.

Exactly! Recently I had the "pleasure" to work with some FORTRAN IV code from the early 60s, so I know what you mean. No functions/subroutines, only GOTOs. Even loops were done with labels. There is also a weird feature called "arithmetic IF statements" (https://en.wikipedia.org/wiki/Arithmetic_IF). Luckily the code was pretty short (about 500 lines including comments).

Re:GOTOphobia Considered Harmful (In C) by bee_rider on Sunday February 26, 2023 @04:55PM (#34949936)
Hmm, it is time to live Cunningham's Law I think:

There’s no good way to do a do…while loop in Fortran, other than a goto.

Re:GOTOphobia Considered Harmful (In C) by spacechild1 on Sunday February 26, 2023 @06:02PM (#34950633)
Early Fortran already had loops, but with labels:

         INTEGER A(4,4), C, R 
         ... 
         DO 10 WHILE ( C .NE. R ) 
                A(C,R) = A(C,R) + 1 
         C = C+1 
  10     CONTINUE

Note that Fortran has evolved significantly over time. This is how you would write the same in Fortran 77:

       INTEGER A(4,4), C, R 
       ... 
       C = 4 
       R = 1 
       DO WHILE ( C .GT. R ) 
              A(C,R) = 1 
              C = C - 1 
       END DO
Re:GOTOphobia Considered Harmful (In C) by bee_rider on Sunday February 26, 2023 @06:18PM (#34950781)
Those are just regular loops, though, right? I’m looking for the posttest loop, sometimes known as the do…while or until loop. There seems to be a unfortunate inconsistency in the naming of this thing.
Re:GOTOphobia Considered Harmful (In C) by spacechild1 on Sunday February 26, 2023 @07:42PM (#34951559)
Ah, right, I misread your post. DO WHILE is indeed a "normal" while loop. There doesn't seem to be an equivalent to "do { ... } while", as found in most C-style languages.

> There seems to be a unfortunate inconsistency in the naming of this thing.

Well, Fortran is older than C, so you cannot really blame them :-)

Re:GOTOphobia Considered Harmful (In C) by bee_rider on Sunday February 26, 2023 @08:26PM (#34951864)
The funny thing is, I mostly program in Fortran (thus the interest in this construct). It is nice for expressing “this iterative method must be run at least once.” Unfortunately at some point I absorbed the name that comes from the C-ism, haha.
Re:GOTOphobia Considered Harmful (In C) by spacechild1 on Monday February 27, 2023 @04:51AM (#34954659)
May I ask what field you're working in? Physics?
Re:GOTOphobia Considered Harmful (In C) by int_19h on Monday February 27, 2023 @04:58AM (#34954693)
A less ambiguous name for those is repeat/until, as seen in Pascal and its descendants - I don't recall any language that uses that syntax for anything other than a postcondition loop.
Re:GOTOphobia Considered Harmful (In C) by pavlov on Sunday February 26, 2023 @03:20PM (#34948959)
This.

To find an example, I did a search for “Commodore PET Basic programs”.

Here’s a book from 1979 that shows what spaghetti code looks like, in my opinion:

http://www.1000bit.it/support/manuali/commodore/32_BASIC_Pro...

The first program listing is on page 24 of the PDF. Try to follow the logic of the program. Why does line 400 go to 280? What paths can lead to line 400? Who knows! And this is high-quality BASIC by 1979 standards — it’s in a printed book after all.

There’s an auxiliary listing after the program itself explaining the routines and variables used, but many/most programs in those days wouldn’t have this level of rigorous documentation. Deciphering the program would probably have to start by drawing a flowchart of execution paths.

Re:GOTOphobia Considered Harmful (In C) by anigbrowl on Sunday February 26, 2023 @03:47PM (#34949237)
Wow, that takes me back. I learned to program on a PET and would have devoured this book had it been available. As it was one of our math teachers was tasked with teaching the computer classes bu didn't have any programming knowledge beyond input/output, loops, and simple calculations. Books and manuals were hard to come by.
Re:GOTOphobia Considered Harmful (In C) by lamontcg on Sunday February 26, 2023 @05:58PM (#34950600)
Also learned to program on a PET in BASIC writing code that was much messier than this because I was probably 10 years old.

Might be why I'm good at restructuring horrible to read spaghetti code.

Re:GOTOphobia Considered Harmful (In C) by Someone on Sunday February 26, 2023 @04:27PM (#34949657)
> And this is high-quality BASIC by 1979 standards — it’s in a printed book after all.

I don’t think that’s true, certainly not for books of that time period. Because the whole field was changing rapidly, writers would often work under tight schedules, and customers would buy about anything because they only had magazines and books to learn from and review sites didn’t exist.

I also think that’s bad Basic for the time. Certainly, comment lines before subroutines would help.

Re:GOTOphobia Considered Harmful (In C) by pavlov on Sunday February 26, 2023 @04:43PM (#34949826)
I would argue that the average program that got printed in a book was probably quite bad but still of a higher quality than the programs people wrote on their own, simply because the latter were usually written without any education or useful models of working programs.

It’s like an iceberg of bad code: the underwater part nobody saw was astonishingly terrible by modern standards. That code might be running a business, but its author would never get exposed to professional programming. Today Excel often serves a similar purpose. (Excel isn’t spaghetti though since the execution model is completely different.)

Re:GOTOphobia Considered Harmful (In C) by codebje on Sunday February 26, 2023 @06:16PM (#34950757)
It looks pretty typical for BASIC of the late 70s to me.

You wouldn't want to waste characters on commenting code: machines of that era would have only a few KB of RAM, as low as 1K. For the same reason you don't want to waste characters on long, meaningful variable names or on well spaced code. Multiple statements per line isn't to save print space, it's to save RAM.

Meanwhile, the program's pretty well structured for such a short bit of BASIC: subroutines start at multiples of 100, for example, and each subroutine starts and ends clearly, no shenanigans like jumping from the middle of one sub to another, no multiple exit points for subs, all as linear as it can be. The use of IF is limited to skipping forward a short way to conditionally execute a line or two only. GOTO only exists in those IF statements.

I'd have been happy to have written code like this, back then.

I am pretty sure that my uncle ran this exact program on his computer and printed out biorhythms on listing paper, in the mid 80s.

Re:GOTOphobia Considered Harmful (In C) by Gibbon1 on Sunday February 26, 2023 @08:40PM (#34951944)
I messed with some programs written in basic for industrial controllers that was written in late 1970's.

There is a simple thing. On a lot of machines only spaghettified programs would even fit in the memory available. Academic CS researchers with their unlimited accounts on the institutions mainframe didn't have that worry.

Re:GOTOphobia Considered Harmful (In C) by deckard1 on Sunday February 26, 2023 @07:10PM (#34951258)
> comment lines before subroutines would help.

That code looks normal to me. I have a ton of BASIC books and magazines. You're talking about a time period before full screen text editors were a thing. It's almost impossible to explain to anyone that didn't have to work with TI-99 BASIC, C64 BASIC, GW-BASIC/BASICA, etc. what it was like. Once you got to QBASIC/QuickBASIC it was done. Life was easy. A few years before that, and you're printing out pages on a dot matrix printer and going line-by-line to debug. You'll notice a distinct lack of white space between lines and that comments start with "REM" and a line number. You didn't even get labels for lines. The code looks like that because those were technology limits on really rudimentary devices. You were editing code inside the BASIC interpreter, often using some command like "LIST <line#>". It was awful.

We take so much for granted today. Dual monitors. Color. More than 80x25 character display. Multiple screens and multitasking. Just getting to Linux in '95 and having F1/F2/F3/etc. switching terminals was a huge deal.

Re:GOTOphobia Considered Harmful (In C) by jamiek88 on Sunday February 26, 2023 @09:00PM (#34952084)
Wasting RAM on REM’s was just rookie stuff.

I remember chasing bytes with short variable names, abbreviated print statements, reducing spaces as much as possible etc.

I had like 28k to play with and I was 14 years old!

Re:GOTOphobia Considered Harmful (In C) by worthless-trash on Monday February 27, 2023 @12:54AM (#34953496)
And we liked it !
Re:GOTOphobia Considered Harmful (In C) by kbelder on Monday February 27, 2023 @06:02PM (#34963246)
I remember in Commodore basic, finding that a period by itself ('.') was parsed as zero, but was actually slightly faster than using zero, and saved a byte every time it was used. In other words, you could write:

    10 for i = . to 6.28 step 0.1:next
and it would be slightly faster and smaller than

    10 for i = 0 to 6.28 step 0.1:next
Made for some ugly inner loops, but you gotta do what you gotta do. For that matter, we certainly would have removed some of those extra spaces as well. Bytes mattered and whitespace slowed you down.
Re:GOTOphobia Considered Harmful (In C) by Closi on Sunday February 26, 2023 @04:31PM (#34949689)
Worth also noting the sort of wild limits with Basic too that are partially responsible for the code being spaghetti, including effectively an inability to add new lines in the code without adding a goto between previous statements.
Re:GOTOphobia Considered Harmful (In C) by bombolo on Sunday February 26, 2023 @07:13PM (#34951303)
What are you talking about?

gwbasic had a function to relabel all the lines. And the labels skip by 10 numbers exactly for the purpose of inserting lines. Then when you had hit the limit you'd ask the computer to relabel them in steps of 10 again.

Re:GOTOphobia Considered Harmful (In C) by klyrs on Monday February 27, 2023 @12:20AM (#34953290)
So many hours of my childhood. Wasted. Damn you. Why didn't you tell me about this then?
Re:GOTOphobia Considered Harmful (In C) by Closi on Tuesday February 28, 2023 @05:46AM (#34967897)
> gwbasic had a function to relabel all the lines. And the labels skip by 10 numbers exactly for the purpose of inserting lines. Then when you had hit the limit you'd ask the computer to relabel them in steps of 10 again.

gw-basic was released c4 years after this book, and there was a huge change over that period:

1976 - Release of Apple I

1977 - Release of Apple II / Commodore PET

1979 - This book

1982 - Commedore 64

1983 - GW Basic

This book is pretty much closer to the Apple I than gw-basic. Perhaps I should have specifically said developing basic in 1979 though as referenced in that book though (and there isn't just one sort of basic - there are so many dialects).

Re:GOTOphobia Considered Harmful (In C) by thaumasiotes on Sunday February 26, 2023 @08:02PM (#34951703)
> The first program listing is on page 24 of the PDF. Try to follow the logic of the program. Why does line 400 go to 280? What paths can lead to line 400? Who knows!

Without looking at the post-program material, this isn't exactly a difficult question to answer.

Line 400 is preceded by some print statements:

    370    PRINT "PRESS 'E' TO END, SPACE TO CONTINUE"
    380    GET R$:IF R$="" THEN [goto] 380
    390    IF R$="E" THEN [goto] 120
    400    L=0:GOTO 280
So we have a prompt that says "press E to end, space to continue", and then branches one of three ways: if you provide no input, the prompt is shown again; if you provide an E, the entire program restarts from scratch, and if you do anything other than that, the count of lines drawn on screen is reset to 0 and the next 18 lines of the chart are drawn.

We can assume that line 400 will be hit whenever a piece of chart is drawn to the screen.

The program's structure here is a nested loop: there is a loop between lines 280 and 400 (displaying the chart indefinitely, 18 lines at a time) containing another loop between lines 300 and 360 (displaying 18 lines of a chart, one line at a time).

Why is this supposed to be an example of spaghetti code?

Re:GOTOphobia Considered Harmful (In C) by j16sdiz on Sunday February 26, 2023 @11:00PM (#34952804)
Now imagine you have got a typo:

    400  L=0:GOTO 290
This would be almost impossible to debug.
Re:GOTOphobia Considered Harmful (In C) by thaumasiotes on Monday February 27, 2023 @04:06AM (#34954454)
That would correspond to the following C:

    /* 280 */
    do_something();
    for (;;) {
      /* 290 */
      /* display chart in blocks of 18 lines */
      /* 400 */
      L = 0;
    }
when the correct code is this:

    for (;;) {
      /* 280 */
      do_something();
      /* 290 */
      /* display chart in blocks of 18 lines */
      /* 400 */
      L = 0;
    }
The bug is that the call to do_something() precedes the outer loop when it should be inside the loop.

Is that easier to debug in C than it is in the BASIC program? What's the difference?

Re:GOTOphobia Considered Harmful (In C) by version_five on Sunday February 26, 2023 @08:25PM (#34951861)
Pretty sure we had that program on our home computer in the 80s (I was a young kid but I distinctly remember a biorhythms program). What impresses me reading it now is the "y2k" compliance. If the year entered is only two digits, it adds 1900, otherwise it takes the full year.
Re:GOTOphobia Considered Harmful (In C) by ivalm on Sunday February 26, 2023 @03:11PM (#34948884)
Do you know of a good example you could link?
Re:GOTOphobia Considered Harmful (In C) by arp242 on Sunday February 26, 2023 @03:28PM (#34949028)
Something like this is the best I could find: https://craftofcoding.files.wordpress.com/2018/01/fortran_go... – the last page has a full listing with arrows to show the jumps.

I grew up with MSX-BASIC: https://github.com/plattysoft/Modern-MSX-BASIC-Game-Dev/blob... – GOSUB jumps to a specific line number (RETURN returns from where it jumped). Even a fairly simple and clean example like this can be rather difficult to follow.

Re:GOTOphobia Considered Harmful (In C) by svieira on Sunday February 26, 2023 @03:20PM (#34948958)
The first part of Guy Steele's talk on Fortress: https://www.infoq.com/presentations/Thinking-Parallel-Progra...
Re:GOTOphobia Considered Harmful (In C) by klyrs on Sunday February 26, 2023 @03:50PM (#34949268)
I dug around a little and found an example [1] on a reddit thread looking for examples of spaghetti code. Most of the examples on the thread were just badly written code. Irreducible spaghetti code tends to be complex state machines that cannot be rendered well in a flat format. People like to flatten those out with a trampoline pattern[2], but that can hinder performance.

Malicious spaghetti involves transformations such as

   for (x = 0; x < 10; x++) {
       for (y = 0; y < 20; y++) {
           printf("%d %d\n", x, y);
       }
   }

   |
   | DRY
   v

   x = 0;
   loop_x_head:
   condition_val = x;
   condition_stop = 10;
   condition_var = 'x';
   goto check_condition;
   loop_x_body:
   y = 0;
   loop_y_head:
   condition_val = y;
   condition_stop = 20;
   condition_var = 'y';
   goto check_condition;
   loop_y_body:
   printf("%d %d\n", x, y);
   increment_val = y;
   condition_stop = 20;
   increment_var = 'y';
   goto increment;
   loop_y_end:
   increment_val = x;
   condition_stop = 10;
   increment_var = 'x';
   goto increment;
   loop_x_end:
   halt;
   increment:
   increment_val++;
   if (increment_var == 'x')
       x = increment_val;
   if (increment_var == 'y')
       y = increment_val;
   condition_val = increment_val;
   condition_var = increment_var;
   check_condition:
   if (condition_val < condition_stop)
       goto pass_condition:
   if (condition_var == 'x')
       goto loop_x_end;
   if (condition_var == 'y')
       goto loop_y_end;
   pass_condition:
   if (condition_var == 'x')
       goto loop_x_body;
   if (condition_var == 'y')
       goto loop_y_body;

[1] http://wigfield.org/RND_HAR.BAS

[2] https://en.wikipedia.org/wiki/Trampoline_(computing)

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.
Re:GOTOphobia Considered Harmful (In C) by zh3 on Sunday February 26, 2023 @04:51PM (#34949900)
I recall having to sort out spaghetti Fortran back in the '80s; numbers as labels (a la basic but with free-form numbering), computed gotos back and forth in the code, stuff like that. Learnt a lot from fixing that mess.

Forty years later, I'll still use a C goto if the situation warrants (e.g. as a getout from deep but simple if). Maybe because having long been an assembler programmer as well, goto's are part of the landscape (if/else is effectively a conditional and unconditional branch/jump).

Re:GOTOphobia Considered Harmful (In C) by inlined on Sunday February 26, 2023 @05:58PM (#34950602)
I used to work at Microsoft on the windows team. There it was very common to have a “goto cleanup” for all early exits. It was clean and readable. Otoh, I once was assigned to investigate an assertion error in the bowels of IE layout code. It was hundreds of stack frames deep in a recursive function that was over a thousand lines long and had multiple gotos that went forwards or backwards. That was an absolute mess and would have been impossible to debug without an recording (“time travel”) debugger.
Re:GOTOphobia Considered Harmful (In C) by astrange on Sunday February 26, 2023 @11:28PM (#34952956)
Any API that returns error codes has that issue; if it just returns an int you can't just set a breakpoint on the "allocate an error" method.
Re:GOTOphobia Considered Harmful (In C) by mort96 on Sunday February 26, 2023 @06:09PM (#34950692)
To give people some kind of an idea of what it was created in response to: Imagine writing an entire program in one single main function. The only thing you're allowed to do for flow control is goto. You can do 'goto somelabel;' for an unconditional goto, or you can do 'if (somecondition) goto somelabel;' for a conditional goto. Here's some examples of how it would look if if translated to something C-like:

Loops would look like:

    int i = 0;
    loop_start:
    print i;
    i = i + 1;
    if (i < 10) goto loop_start;
Fizzbuzz would look something like:

    int i = 0;
    loop_start:
    if (i % 5 != 0) goto not_fizzbuzz;
    print "fizzbuzz";
    goto done;
    not_fizzbuzz:
    if (i % 3 != 0) goto not_fizz;
    print "fizz";
    goto done;
    not_fizz:
    if (i % 5 != 0) goto not_buzz;
    print "buzz";
    goto done;
    not_buzz:
    print i;
    done:
    i += 1;
    if (i < 100) goto loop_start;
Often, this wasn't just constrained to a single function; the whole program would be constructed like this, with gotos which jump back and forth across pages and pages of code. Languages wouldn't even have a call stack with subroutines (which is why "procedural" languages -- languages with procedures -- were important enough to be given a special name).

At least that's my understanding of it. I haven't lived through this, and my only experience with this kind of stuff is writing assembly, where we always make use of a call stack, so even that is in practice a procedural language. If I have gotten anything wrong, please correct me.

Re:GOTOphobia Considered Harmful (In C) by fsckboy on Sunday February 26, 2023 @07:38PM (#34951513)
tangentially, can somebody point me to what are considered the best fizzbuzz solutions? I'm both an experienced and cs-educated coder, and I know what I would consider to be a good solution, but I have no idea what the rest of "you" are looking for. (my favored solution would be a small number of state machines running in parallel to sieve-of-eratosthenes the correct answers thus avoid innumerable divisions, but maybe that's just me and I'm old fashioned?)
Re:GOTOphobia Considered Harmful (In C) by anonymoushn on Sunday February 26, 2023 @11:43PM (#34953059)
Surely your compiler won't actually emit an integer modulus if you tell it to mod by a constant?
Re:GOTOphobia Considered Harmful (In C) by _kst_ on Monday February 27, 2023 @01:00AM (#34953520)
I don't claim to have the best, or even good, fizzbuzz implementations, but if you're looking for a lot of fizzbuzz implementations:

https://github.com/Keith-S-Thompson/fizzbuzz-c

https://github.com/Keith-S-Thompson/fizzbuzz-polyglot

Re:GOTOphobia Considered Harmful (In C) by zozbot234 on Sunday February 26, 2023 @08:10PM (#34951748)
The loop you posted is a do-while loop; the while loop has a somewhat less intuitive translation to GOTO:

  loop_test: IF (NOT loop_condition) GOTO after_loop
    loop_body
    GOTO loop_test
  after_loop: etc...
Re:GOTOphobia Considered Harmful (In C) by dheera on Monday February 27, 2023 @12:12AM (#34953239)
Not too far from assembly ...
Re:GOTOphobia Considered Harmful (In C) by mort96 on Monday February 27, 2023 @04:51AM (#34954664)
Almost, except in assembly, we always have a call stack. So even assembly is a procedural language, even though it doesn't otherwise have structured control flow.
Re:GOTOphobia Considered Harmful (In C) by _kst_ on Monday February 27, 2023 @12:56AM (#34953506)
Could be worse.

https://github.com/Keith-S-Thompson/fizzbuzz-c/blob/master/f...

    #include <stdio.h>
    #include <setjmp.h>
    int main(void) {
        jmp_buf jb[7];
        volatile int j = 0;
        setjmp(jb[0]);
        volatile int i = 1;
        if (j == 0) setjmp(jb[1]);
        if (j == 1 && i > 100) longjmp(jb[6], 0);
        if (j == 1 && i % 15 == 0) longjmp(jb[4], 0);
        if (j == 1 && i % 3 == 0) longjmp(jb[2], 0);
        if (j == 1 && i % 5 == 0) longjmp(jb[3], 0);
        if (j == 1) printf("%d\n", i);
        if (j == 1) longjmp(jb[5], 0);
        if (j == 0) setjmp(jb[2]);
        if (j == 1) puts("Fizz");
        if (j == 1) longjmp(jb[5], 0);
        if (j == 0) setjmp(jb[3]);
        if (j == 1) puts("Buzz");
        if (j == 1) longjmp(jb[5], 0);
        if (j == 0) setjmp(jb[4]);
        if (j == 1) puts("FizzBuzz");
        if (j == 0) setjmp(jb[5]);
        i ++;
        if (j == 1) longjmp(jb[1], 0);
        if (j == 0) setjmp(jb[6]);
        j ++;
        if (j  < 2) longjmp(jb[0], 0);
    }
Re:GOTOphobia Considered Harmful (In C) by ziml77 on Monday February 27, 2023 @01:41PM (#34960250)
I am sobbing in pain at that atrocity.
Re:GOTOphobia Considered Harmful (In C) by _kst_ on Monday February 27, 2023 @03:50PM (#34961684)
I live to serve.
Re:GOTOphobia Considered Harmful (In C) by int_19h on Monday February 27, 2023 @04:56AM (#34954683)
Procedural or not was more of a spectrum. If you look at early BASICs, for example, they had GOSUB, and it could recurse, so there was a return-address stack. But GOSUB did not have any provisions to pass arguments or return values - it was just a GOTO that remembered where it came from; you had to use globals to pass data around. So if you wanted a data stack (i.e. locals), you had to rig your own with arrays.

OTOH early FORTRAN had procedures with arguments and results, but no recursion.

Structural or not was also not necessarily all-in. FORTRAN and BASIC both had for-loops before they had structured conditionals.

Re:GOTOphobia Considered Harmful (In C) by girvo on Sunday February 26, 2023 @06:42PM (#34951004)
The last time I encountered that kind of code was when I wrote it myself in VB6 as a kid. I’ve never seen it in my decade and a half work life.
Re:GOTOphobia Considered Harmful (In C) by Jtsummers on Sunday February 26, 2023 @06:47PM (#34951046)
You're lucky. If you want to feel comfortable on a plane, don't work on avionics systems written in the 1970s-1980s (and probably a lot from the 1990s). Some horrifically bad code running some planes.
Re:GOTOphobia Considered Harmful (In C) by DonHopkins on Sunday February 26, 2023 @07:28PM (#34951443)
BASIC. The only thing worse than gotos is line numbers.
Re:GOTOphobia Considered Harmful (In C) by jamesfinlayson on Sunday February 26, 2023 @07:29PM (#34951455)
Yeah I saw a codebase written in Fortran 77 (the program was written in 1988 or 1989 I believe) and geez... it is almost impossible to figure out what is going on. Programming has changed a lot.
Re:GOTOphobia Considered Harmful (In C) by dilyevsky on Sunday February 26, 2023 @08:57PM (#34952060)
> The thing is that many people today have never encountered the sort of spaghetti code that Dijkstra was talking about in 1968.

I would say js/python callback-based frameworks of today like Twisted (also c++/rust futures) is exactly that

Re:GOTOphobia Considered Harmful (In C) by kevin_thibedeau on Sunday February 26, 2023 @10:08PM (#34952474)
I've seen full spaghetti on recently written C driver code for an IC. The device contained a 24-bit processor that wouldn't have a compiler and its one-man dev team was necessarily doing all of the firmware in assembly. He basically wrote all of the C with assembly style control flow, goto-ing all over the place and zero high level statements.
Re:GOTOphobia Considered Harmful (In C) by pjmlp on Monday February 27, 2023 @01:09AM (#34953562)
I kind of have, instead of GOTOs, we have RPC calls on the flavour of the day, that just GOTOs only make sense after doing a full diagram of call sequences.

Just like 8 bit BASIC spaghetti code, only refined.

Re:GOTOphobia Considered Harmful (In C) by Natsu on Monday February 27, 2023 @02:49AM (#34954053)
> I'm not that old, but I was unlucky enough to have programmed in an unstructured language where GOTO was the only way to use faux-subroutines in my teens.

Was that a Casio calculator? Because it was like that for me, only GOTOs existed. Learning about C and seeing these things called loops was a revelation because I had reinvented them with GOTOs already in my programming.

Re:GOTOphobia Considered Harmful (In C) by PaulHoule on Monday February 27, 2023 @01:11PM (#34959872)
BASIC?

GOSUB was so much worse than GOTO in that it had a stack for the current line but no stack for variables so you could not write recursive functions. I think Fibonacci as a recursive function is malpractice but boy was it a hassle to write Quicksort in BASIC although I had no trouble coding up an FFT (1950s FORTRAN style) from first principles in BASIC on TRS-80 Model 100 on a bus ride across Vermont.

Funny though I did come to a conclusion that for the Arduino programs I wrote I didn’t need a stack at all.

Re:GOTOphobia Considered Harmful (In C) by wglb on Tuesday February 28, 2023 @08:02PM (#34977342)
I read the paper when it first came out. At the time I was programming in Fortran which had the three branch if-statements. As you pointed out, that was a special kind of hell. The paper rang very true. However we did all take it to the extreme and go for zero goto with quite a fervor.
Re:GOTOphobia Considered Harmful (In C) by josh11b on Sunday February 26, 2023 @06:08PM (#34950690)
[1] on structured concurrency gives good context for Dijkstra's GOTO paper and how it is applicable today.

[1] https://vorpus.org/blog/notes-on-structured-concurrency-or-g...

Re:GOTOphobia Considered Harmful (In C) by tialaramex on Sunday February 26, 2023 @06:49PM (#34951072)
Sure, it's a good letter, and indeed it's about this problem where people use a go-to or jump control flow with no structure whereas by the time he wrote that letter there were well understood structures (like: functions) to prefer.

However, while I sympathise with a C programmer who feels goto is necessary in their language, I think that speaks to a problem in the language rather than the programmer. If you have better structural support in your language you can express the things the author (of the link, not Dijkstra) wants to express without needing this unstructured go-to.

For example Rust's break 'label value; allows us to mark any compound expression with the 'label, and then say from anywhere inside that expression but nowhere else that we've decided the value of the expression overall and here's what it is.

This doesn't feel that different from what is being done here with goto, except for two crucial things as a result of being structured:

1. Rust will type check this, if this region of the program picks a Dog, our break needs to provide a Dog, it can't just shrug and expect the program to continue without one. This means maintenance programmers don't need non-local reasoning, this region of the program does, in fact, always pick a Dog, albeit the break 'label value is something to look closely at if you're reading that region itself.

2. We cannot do this, even by mistake (e.g. as a result of copy-paste) across scopes. If you try to break 'label result from the cat care loop into the dog loop earlier in the same function, that just doesn't compile, whereas that C goto has no problem attempting that (a good C compiler should notice if you try to do something really egregious, but good luck).

Re:GOTOphobia Considered Harmful (In C) by zozbot234 on Sunday February 26, 2023 @07:56PM (#34951663)
> It's better when the lexical structure of the source code maps to the execution structure.

Sure, but that has nothing to do with whether the GOTO statement should be used. The semantics of GOTO are arguably quite clear; they amount to setting a different continuation for the running program. (Semantically, this implies that the precondition of the GOTO statement is made a possible precondition for the label that the statement jumps to; and execution simply does not proceed to the next statement.)

There are even "relooper" algorithms to reconstruct a structured program from patterns in the idiomatic use of GOTO statements: they are used in compiling to structured object languages such as WASM code. Using GOTOs in an idiomatically sensible way (avoiding spaghetti code) may be less readable than writing actual structured blocks, but only slightly so.

Re:GOTOphobia Considered Harmful (In C) by kbumsik on Sunday February 26, 2023 @09:17PM (#34952167)
And the original paper is published even before the first version of C was introduced.
Re:GOTOphobia Considered Harmful (In C) by sedatk on Sunday February 26, 2023 @10:51PM (#34952740)
That wasn’t even Dijkstra’s title. It was Niklaus Wirth who edited the title in. I mention that in Street Coder.
Re:GOTOphobia Considered Harmful (In C) by bazoom42 on Monday February 27, 2023 @01:47AM (#34953781)
Interestingly, many seem to want to project their own opinion upon Dijkstra.

Dijkstra is clearly arguing for a “single entry single exit” style. But modern consensus seem to uphold single entry but accept multiple exits from a block. Break, continue, early returns, exceptions - all are example of multiple exit. These are more constrained than gotos but nevertheless Dijkstras argument applies to them also.

I personally belive early returns can greatly improve readability (when not nested too deep) an that exceptions are typically cleaner than the alternative. But I acknowlede Dijkstra would disagree.

Re:GOTOphobia Considered Harmful (In C) by mFixman on Monday February 27, 2023 @05:25AM (#34954835)
IIRC multiple entry points were common in Dijkstra's times.

Break, continue, and early returns always return to the end of the block, unlike goto in the '70s. Exceptions are more complicated, and the cause of a lot of inunderstandable programs.