10 ms·
What a weird post. There's so many cool things Fortran does better than C-like languages, but instead the post focuses on superficial syntax like labelled loops
by nmilo 5y ago
What a weird post. There's so many cool things Fortran does better than C-like languages, but instead the post focuses on superficial syntax like labelled loops and dangling elses. The labelled loops thing particularly irks me because it's a so often repeated qualm about C yet it's performing the exact same function as a goto--so why not use a goto?
- asddubs 5y agoyeah I was expecting stuff like not allowing aliasing, which allows the compiler to optimize functions better
- nusaru 5y agoI guess some people are afraid to use a gun for fear that they might shoot their foot—or that someone else will. I think goto’s are useful.
- rightbyte 5y agoThere is a dogmatic contempt for goto:s. Like people who use them are stupid or something and obviously doing it wrong. I think the underlying reason is that it is annoying to write tree walking interpreters and implement goto:s. (How do you even do that?). So the prominent CS folks at the time just dismissed goto:s instead by bullying user to submission.
- scambier 5y agoThe contempt is justified. `goto`s break the flow and make the code harder to read and reason about, and thus make it easier to introduce bugs. It's an instruction that's almost never _needed_ today, because there is always a better structure to use instead. I only use it in Lua, to compensate for a lack of `continue` in loops.
- cyberpunk 5y agocybrpnk:~/src/linux$ grep -rniE 'goto\W+.*;' . | grep -E '\.[c|h]:' | wc -l 182044 Sure.. I mean.. 'almost'
- dan-robertson 5y agoIt’s worth noting: 1. One need for goto in C is for what is done with labelled loops in other languages. So one might expect uses there 2. Another use is for cleanup after errors which would be automatically handled by the compiler (via destructors) in most more modern non-gc languages. It looks like: int do_thing(args…){ foo *x; bar *y; baz *z; int err; if((err = make_foo(&x, …)) < 0) goto exit3; if((err = make_bar(&y, …)) < 0) goto exit2; if((err = make_baz(&z, …)) < 0) goto exit1; frob(foo, bar, baz); err = 0; /* maybe use x,y,z and return instead of cleanup */ free_baz(z); exit1: free_bar(y); exit2: free_foo(x); exit3: return err; } So really all you’re proving is that C does not provide sufficiently useful structured programming tools to avoid goto. Java handles this fine for memory but not so nicely for objects that have more involved cleanup that shouldn’t be delayed (e.g. open files, removing from some parent object, etc). Indeed Java also doesn’t provide great tools for protecting cleanup code from stack unwindings, or at least they aren’t sufficiently ergonomic that you see them used everywhere. It certainly isn’t the case that Linux is full of old-school do-whatever-you-like uses of goto.
- _0ffh 5y agoMeh, that's just the kind of dealing in absolutes that gets on some peoples' nerves. I agree that in almost all situations gotos are probably not the best choice, but there are still situations where gotos are a reasonable option, arguably even the best that's available.
- Jtsummers 5y agoThat's a very ahistorical take. The primary reason to move away from go to statements was around reasonability. Structured programming introduced semantically meaningful control structures which replaced the vast majority of the uses of go to statements. Go to statements, themselves, don't carry the same meaning with them (is it part of a loop, a conditional, a subroutine call, a return from a subroutine, moving to an error handler?), go to statements also permit spaghetti code which is somewhere between hard and impossible to express in most languages using structured programming control structures.
- rightbyte 5y agoYe sure I agree. Structured programming was a rational displacement of goto:s. I think it took Fortran like 20 years before it got proper loop constructs and you could essentially write to the instruction register with assigned goto, like Fortran was some Macro Assembler. But the contempt goes further than "goto vs subroutine calls" or "goto vs the if-else construct". With "underlying reason" I meant more like "underlying reason for the contempt of all use of goto". Even when goto makes the code less spaghetti and more readable. Knuth did a good write up on the matter: https://pic.plover.com/knuth-GOTO.pdf https://pic.plover.com/knuth-GOTO.pdf
- Jtsummers 5y agoWhat you initially wrote, and what I was replying to: > I think the underlying reason is that it is annoying to write tree walking interpreters and implement goto:s I don't believe that there is any historical justification for this view. And your updated statement is even less historically sound. Everything written about go to statements (as a negative, something to partially or fully eliminate) seems to have been predicated on reasonability and comprehensibility of the code by people, not the ability to write tree walking interpreters. Which is a minor activity when reviewing the totality of all computer programming activities of the past 70 or so years.
- tehjoker 5y agoI don't get why people are so afraid of goto. I looked into Dijkstra's original invective against it and it was an argument for structured programming. People may not be familiar with that term because it won so thoroughly that only assembly programmers work outside if it. It means constructs like loops, functions, if statements, etc. In dijkstra's world, people just jumped to any code anywhere in the program, leading to insane spaghetti code that was impossible to read. In C++, goto can no longer jump to anywhere in the program, only within the function. This severely limits the potential damage of goto if the functions are otherwise well constructed. goto can be used for high performance decision trees, loop exiting, and in C (less so in C++ due to RAII) for freeing memory at the end of a function. I used to fear goto, no longer. However, I would advocate using it only in those situations (possibly others) as in excess it will lead back to the same problems identified by Dijkstra.
- grumpyprole 5y agoYes there's nothing wrong with goto if you need it. Of course, if you are just doing a loop, then a loop structure better communicates the intent and is safer. This is just abstraction and its a good thing. An example from functional programming is direct recursion versus maps/folds, again better to use these abstractions when possible, but direct recursion offers the most flexibility.
- disgruntledphd2 5y ago> People may not be familiar with that term because it won so thoroughly that only assembly programmers work outside if it. I read an old edition of Numerical Recipes, and the first chapter or two was a paean to structured programming, which is when I realised that for, while etc hadn't sprung full-form from the heads of the first compiler developers.
- 10000truths 5y agoThere are several good uses for goto in C. Here's a few I can think of, off the top of my head: 1. Breaking out of nested loops. Sure, you can kludge this with a flag variable, but goto is far more readable. 2. Implementing resource cleanup with stack-style unwinding semantics (i.e. RAII-like). The alternative is usually a bunch of nested if statements, which makes things much harder to read. 3. Implementing state machines. goto is very good at expressing transitions in a graph-like state machine. It doesn't inflate code size as using inline functions would, and it doesn't incur register/stack setup costs that non-inline functions would. However, readability becomes somewhat difficult as the state machine gets more complex, so this is usually relegated to code generators like SMC, re2c, or Ragel. 4. Dispatch loops for threaded virtual bytecode. This is especially niche, and it relies on the labels-as-values gcc extension, but it is very important for implementing performant interpreters. The average C programmer won't necessarily encounter all of these use cases in their career, but that doesn't make any individual one any less important.
- taeric 5y agoJava also has labeled loops. Such that I have used it before. Not nearly as easy to abuse as goto statements.
- dan-robertson 5y agoJava needed labelled loops because it deliberately did not include goto, so I don’t really see the argument. If you have goto then you don’t need labelled loops (this is a much less bad argument than ‘if you have goto you don’t need any other control flow’ as using labelled loops and using goto are similar) but it might be scary to have all the freedom of it.
- taeric 5y agoMy point was that there is later evidence in language implementation that labeled loops aren't that dangerous.
- jcranmer 5y ago> it's performing the exact same function as a goto--so why not use a goto? The 'break' keyword does the exact same function as a goto, why not use a goto? The 'continue' keyword does the exact same function as a goto, why not use a goto? ... Actually, let's play the game even further. The 'else' keyword does the exact same function as a goto. So do 'while' and 'for' and 'do'/'while'. The only things you actually need are 'if' and 'goto', everything else is merely syntactic sugar on top of that. But it turns out that syntactic sugar does have value. The break and continue keywords are nothing more than gotos that are restricted to breaking out of the innermost loop or continuing to the next loop iteration, respectively, and so you can understand what they do without having to track down the label (or indeed, come up with a name for the label!). It's more mystifying to me that some languages don't extend the syntax to refer to an arbitrary loop in the current loop nest. In fact, it turns out that labeled break and continue are sufficient to allow you form nearly every possible control-flow graph... and the kind that it doesn't is the one I don't want you to be able to form, speaking as a writer of compiler optimizations.
- nmilo 5y agoNot sure what your point is. C doesn't have labelled loops, so a goto signals intent better than the weird exitloop=1 thing in the article. This isn't to say C shouldn't have labelled loops; I think they're better than gotos, it's just that the C committee will likely never add them one of C's philosophies (goals?) is to limit syntactic sugar.
- gdwatson 5y ago> The 'break' keyword does the exact same function as a goto, why not use a goto? The 'continue' keyword does the exact same function as a goto, why not use a goto? A break from a named loop is one statement and a label. A goto is one statement and a label. You don’t lose structure by putting the label at the end of the loop instead of the beginning. Unnamed break is incredibly common, so having a built-in shorthand is quite ergonomic; it also lets you avoid defining a label, which named break doesn’t do. The argument for continue is similar, but continue is less common and maybe doesn’t justify its keyword status. else, for, and do-while all take blocks, so they have the opportunity to encode structure in a way that a break from a named loop doesn’t.
- TheRealKing 5y agoOn the contrary, these are, in my opinion, excellent examples, although not a comprehensive list, of where Fortran shines compared to other languages that do not have such advantages or new languages that desperately try to copy, mimic, and rebrand the decades-long existing features of Fortran under their names.