Probably coming too late to the discussion, but commenting anyway... The issue I think is that people today read "GOTO Considered Harmful" without really understanding the world at the time. Other than simple integer FOR loops, basically all control-flow in the FORTRAN of those days was accomplished with GOTO -- and to numbered lines, not labels. Things we take for granted in all languages today like { code blocks }…
This is my pet peeve with how they teach kids programming. Granted, I only have anecdata on that topic, gleaned from how they teach my own kid at school, but I still can't shake the feeling that we're doing them a disservice by making them skip straight to JavaScript or Python. I wonder what it would be like if kids started with BASIC. And not Visual Basic or any other modern, structured flavor. No, I mean the ancien…
Goto (2007)
191–200 of 207 posts
Re: Goto (2007)
#192Probably coming too late to the discussion, but commenting anyway... The issue I think is that people today read "GOTO Considered Harmful" without really understanding the world at the time. Other than simple integer FOR loops, basically all control-flow in the FORTRAN of those days was accomplished with GOTO -- and to numbered lines, not labels. Things we take for granted in all languages today like { code blocks }…
Can you give an example of where you've used goto in C or a C-like language? Or a rough estimate of the number of times you've found goto to be the best solution? I agree with your post in principle, but in practice I can't think of a single example where I've used a goto that wasn't eventually refactored to something better that didn't have the goto. Edit: Probably the most common example (and one given early in the…
For example, if a file is locked for writing, I want to wait for 5, then 10, then 15 seconds, retrying each time, before giving up.
In such case I do not want the retrials loop to be my main control structure.
Instead, I jump from inside the IO exception catch block to the ReTry label, restarting the whole operation.
This makes the flow fairly clean.
Re: Goto (2007)
#193Beej’s Guide to C Programming [pdf] - https://news.ycombinator.com/item?id=26911399 - April 2021 (171 comments)
Beej's Guide to C Programming - https://news.ycombinator.com/item?id=26100391 - Feb 2021 (1 comment)
Beej's Guide to C Programming (2007) - https://news.ycombinator.com/item?id=15198093 - Sept 2017 (79 comments)
Beej's Guide to C Programming - https://news.ycombinator.com/item?id=8295024 - Sept 2014 (1 comment)
Re: Goto (2007)
#194Earlier quoted context omitted.
Can you give an example of where you've used goto in C or a C-like language? Or a rough estimate of the number of times you've found goto to be the best solution? I agree with your post in principle, but in practice I can't think of a single example where I've used a goto that wasn't eventually refactored to something better that didn't have the goto. Edit: Probably the most common example (and one given early in the…
> deeply nested loops. [...] I will prefer to hide one or more of the inner loops inside of a function call. And I would too... but sometimes there are too many local variables involved to do that cleanly. And, ultimately, if you are making your code less clean to avoid using a goto then you avoided unwisely. > Can you give an example of where you've used goto in C or a C-like language? Well there have been several f…
But yep, I have no complaints with the code as presented.
Re: Goto (2007)
#195Probably coming too late to the discussion, but commenting anyway... The issue I think is that people today read "GOTO Considered Harmful" without really understanding the world at the time. Other than simple integer FOR loops, basically all control-flow in the FORTRAN of those days was accomplished with GOTO -- and to numbered lines, not labels. Things we take for granted in all languages today like { code blocks }…
Can you give an example of where you've used goto in C or a C-like language? Or a rough estimate of the number of times you've found goto to be the best solution? I agree with your post in principle, but in practice I can't think of a single example where I've used a goto that wasn't eventually refactored to something better that didn't have the goto. Edit: Probably the most common example (and one given early in the…
1 every 160 lines is a goto, and that's just a naive count so includes all header and preprocessor gunk, whitespace, some generated C code, comments, etc.
If you're talking about more pure lines if C, it would probably be close to 1% of statements are goto.
It might not be everyone's cup of tea as the pinnacle of C programming, but it's a real highly used medium-large project that has coped well with a pretty high rate of change from a very wide spectrum of contributors. So it is a good real world example of open C code you can look at that is maintainable while making a lot of use of goto.
Re: Goto (2007)
#196Probably coming too late to the discussion, but commenting anyway... The issue I think is that people today read "GOTO Considered Harmful" without really understanding the world at the time. Other than simple integer FOR loops, basically all control-flow in the FORTRAN of those days was accomplished with GOTO -- and to numbered lines, not labels. Things we take for granted in all languages today like { code blocks }…
Can you give an example of where you've used goto in C or a C-like language? Or a rough estimate of the number of times you've found goto to be the best solution? I agree with your post in principle, but in practice I can't think of a single example where I've used a goto that wasn't eventually refactored to something better that didn't have the goto. Edit: Probably the most common example (and one given early in the…
> "I will prefer to hide one or more of the inner loops inside of a function call."
That risks the additional unnecessary overhead of a function call, which can be expensive in a loop, and not all compilers are as good at optimizing as they should be.
Re: Goto (2007)
#197Earlier quoted context omitted.
> using SHA-1 as a non-secure hash, That I actually partly disagree with. There are much, MUCH better performing (faster, less memory use, etc) hashes than SHA1 if you don't need security. If you don't need security, and you don't need performance, and you don't have anything else available in libraries, then SHA1 is fine. But that's a pretty rare situation. SHA1 might not be a sign of insecurity, but it's often a si…
On modern Intel/AMD and ARM CPUs, which have SHA-1 instructions, SHA-1 is very fast, faster than many apparently simpler hashes. There are no other so fast hashes with an output of at least 128 bits that you can find in available libraries and use immediately in your code. The only alternative that is faster and long enough is to use an 128-bit polynomial hash like Poly1305 or the one used inside AES-GCM. Such polyno…
SIMD optimizations are arguably more important than multithreading. Take a look at these SUPERCOP benchmarks on a recent Intel CPU: https://bench.cr.yp.to/results-hash.html#amd64-pascalinspiro.... Those are all single-threaded measurements, and the SHA-1 implementation there is hardware-accelerated, but BLAKE3 is still almost 4x faster. That speedup comes from AVX-512 vector operations, which serial hashes like SHA-1 can't take (as much) advantage of. Not every caller will want to use the AVX-512 implementation (see "downclocking"), but even with AVX2 BLAKE3 would still be faster.
Multithreading is a nice option to have, and of course it looks great in benchmarks if the input is long enough. But general-purpose library APIs like `blake3::hash()` in Rust don't do multithreading by default. They only use SIMD optimizations by default.
Re: Goto (2007)
#198Goto is a useful precursor for writing a tail recursive solution. For instance, say we have a state machine for recognizing that the last four button presses were 1234. int keypad() // returns 1 if correct key is entered, otherwise loops forever { keypad: switch (getkey()) { case 1: goto got_1; default: goto keypad; } got_1: switch (getkey()) { case 2: goto got_2; case 1: goto got_1; default: goto keypad; } got_2: sw…
int keypad()
{
int state = 0; // 0 = start, 1 = seen '1', 2 = seen '12', 3 = seen '123'
while (true) {
int key = getkey();
switch (state) {
case 0:
switch (key) {
case 1:
state = 1;
default:
state = 0;
}
break;
}
case 1:
switch (key) {
case 1:
state = 1;
case 2:
state = 2;
default:
state = 0;
}
break;
}
case 2:
switch (key) {
case 3:
state = 3;
case 1:
state = 1;
default:
state = 0;
}
break;
}
case 3:
switch (key) {
case 4:
return 1;
case 1:
state = 1;
default:
state = 0;
}
break;
}
}
}
In my mind that reads more obviously as a state machine than a bunch of gotos and labels (and should function the same assuming I typed it correctly, I haven't run it anywhere). It's easy to see each state and how it flows into other states.Re: Goto (2007)
#199Earlier quoted context omitted.
Perhaps that's true when you're writing performance-critical code. For most code, readability trumps micro-optimizations.
In plenty of environments, there's a very limited number of calls you can make before the program fails entirely. For instance, in GW-BASIC, your namesake, the limit is less than 100 calls. There are plenty of real useful production langauges where your stack will run out before 1000 frames of depth. But on the other hand, it's quite reasonable to write a state machine which is expected to make [mb]illions of state t…
When I wrote in GW-Basic, I only used gotos. Most of the example code that I had access to used gotos.
I was 11 years old at the time.
> There are plenty of real useful production langauges where your stack will run out before 1000 frames of depth
That wouldn't surprise me in an embedded environment. But if that's the case for a run of the mill general purpose programming language that's running a typical web application, I'd be shocked.
Re: Goto (2007)
#200Probably coming too late to the discussion, but commenting anyway... The issue I think is that people today read "GOTO Considered Harmful" without really understanding the world at the time. Other than simple integer FOR loops, basically all control-flow in the FORTRAN of those days was accomplished with GOTO -- and to numbered lines, not labels. Things we take for granted in all languages today like { code blocks }…
I still run spitbol. Regardless of its assembly-like control flow, I think the pattern matching beats PCRE, and Lua's implementation of LPeg.