Just... out of curiosity as someone who learned to code in BASIC on a TRS-80... WHY ON EARTH would you ever want goto or gosub statements instead of proper loops and methods? It's not like they're faster. They certainly don't make code more readable. The last time I had to use that type of construct was gotoAndStop() in Flash, which at least had the benefit of queueing up a bunch of art and sound effects. Other than the "neat-o" factor, what's the use case or impetus behind this apparent horror?
I had to use GOTO label, once so far, as a way to quickly exit from inside nested loops - you can do it without GOTO but the point was to be efficient(like if you work with the pixel colors of a big image , each extra instruction inside the loops will have a visible time effect).
In a situation like that I would usually define a boolean before entering the top loop, and set that true within once a condition is met, causing all the outer loops to break if that condition is true. I can't imagine there would be a major speed difference in some other way of breaking all the loops to jump to a different line of code.
That means once it’s set to true, all the inner loops would need to at least finish that iteration. That could be a huge speed difference at a minimum or a completely wrong implementation.
this means you do a if check each loop, this is bad if you do some say image filter/effect where you work with big loops. end you get some nested if and break inside the code, is much more readable to just jump out.
Pythons for-loop is not working with boolean, so using one would mean to uglify the code. A goto would simplify the workflow by removing 1-2 lines for each additional loop.
probably faster since it was built for this purpose, throwing an error would have to at least create an exception object, then create stack trace and the other setup stuff.
As i said I code for almost 20 years and I only had to use it once so far, but people that maybe work a lot more with stuff that needs a lot of performance might use it much more often.
First of all, you wouldn't want it. I am an old programmer, so I still remember being taught to code before structured programming became universal. And I can personally attest the structured programming was a great advance.
In case you haven't heard the term, structured programming is the term that was used for replacing goto with a handful of commonly used control flow structures. A loop, a function with a return statement, and some kind of case statement (or multi branch if) were the basic ones.
If you look at modern languages today almost all of them have the same set of control flow constructs. They have an if statement, a loop, some kind of function with a return statement, most have some kind of case or multi-branch if, and must have some sort of exceptions. (If was present before structured programming; exceptions were added later.)
If you look at the very oldest programming languages they may have some of these control flow structures but they definitely have two: the if statement and the goto. Because the goto statement is strictly more powerful than these other control structures. If you have a language that doesn't support exceptions but does have a goto, then you can write an exception-like flow using goto. If you have a language that doesn't have break or continue for its loops you can build a loop that works that way using goto. If you're programming language doesn't have the broken form of case statement (that falls through to the next branch) so you can't build Duff's device [https://en.m.wikipedia.org/wiki/Duff%27s_device], then you can build that using goto.
In fact, the combination of if and goto is powerful enough to create any possible (single threaded) flow control structure including ones you and I have never even thought of.
The reason that structured programming was such an important and powerful step forward is because it made the language strictly less powerful. Because the language was less powerful, it was possible to reason more clearly about what the code could or couldn't do. In particular, it allowed a programmer to make certain assumptions about locality. If you started reading at the top of a function and worked your way down you could reason about what this function did in isolation: perhaps the tangle of loops and ifs and try-except blocks in the function are confusing, but at least you don't have to read the entire rest of the program to be certain what it is doing. With goto in your language that guarantee is gone: you might have to understand the entire rest of the program in order to figure out any one function.
So, we gave up the power to create certain flow control constructs in order to make it possible to reason about our languages. But there is nothing that says that the evolution of programming languages is finished. Exceptions are pretty nifty, and they were not part of the original toolkit. Maybe there is another control flow structure out there waiting to be discovered which is extremely useful for solving certain kinds of problems. Someone with goto in their language could discover and use that control flow structure, while those of us without goto cannot.
With goto in your language that guarantee is gone: you might have to understand the entire rest of the program in order to figure out any one function.
The same is true, to a greater degree, for function calls.
I guess that depends on if the language supports tail recursion and/or you're 100% sure it won't blow the stack. If you need to retry forever, without using any memory to do so, goto is perfect.
Comments
Just... out of curiosity as someone who learned to code in BASIC on a TRS-80... WHY ON EARTH would you ever want goto or gosub statements instead of proper loops and methods? It's not like they're faster. They certainly don't make code more readable. The last time I had to use that type of construct was gotoAndStop() in Flash, which at least had the benefit of queueing up a bunch of art and sound effects. Other than the "neat-o" factor, what's the use case or impetus behind this apparent horror?
I had to use GOTO label, once so far, as a way to quickly exit from inside nested loops - you can do it without GOTO but the point was to be efficient(like if you work with the pixel colors of a big image , each extra instruction inside the loops will have a visible time effect).
In a situation like that I would usually define a boolean before entering the top loop, and set that true within once a condition is met, causing all the outer loops to break if that condition is true. I can't imagine there would be a major speed difference in some other way of breaking all the loops to jump to a different line of code.
That means once it’s set to true, all the inner loops would need to at least finish that iteration. That could be a huge speed difference at a minimum or a completely wrong implementation.
this means you do a if check each loop, this is bad if you do some say image filter/effect where you work with big loops. end you get some nested if and break inside the code, is much more readable to just jump out.
I would argue that having to do that is not in fact a 'proper' loop. Your way and goto are both workarounds for a missing control flow construct.
For gosub, what's the issue? It is a method call.
Pythons for-loop is not working with boolean, so using one would mean to uglify the code. A goto would simplify the workflow by removing 1-2 lines for each additional loop.
Is that faster than (or comparable to) raising an Error in the inner loop and catching it outside the outer loop?
Internal error bubbling code is slow and can change from release to release. And it's definitely not intended for the job.
probably faster since it was built for this purpose, throwing an error would have to at least create an exception object, then create stack trace and the other setup stuff.
As i said I code for almost 20 years and I only had to use it once so far, but people that maybe work a lot more with stuff that needs a lot of performance might use it much more often.
Read "Structured programming with goto" by Knuth (a paper). He gives a quite in depth explanation of when gotos could be preferable.
Also, if you generate code then gotos can be useful.
First of all, you wouldn't want it. I am an old programmer, so I still remember being taught to code before structured programming became universal. And I can personally attest the structured programming was a great advance.
In case you haven't heard the term, structured programming is the term that was used for replacing goto with a handful of commonly used control flow structures. A loop, a function with a return statement, and some kind of case statement (or multi branch if) were the basic ones.
If you look at modern languages today almost all of them have the same set of control flow constructs. They have an if statement, a loop, some kind of function with a return statement, most have some kind of case or multi-branch if, and must have some sort of exceptions. (If was present before structured programming; exceptions were added later.)
If you look at the very oldest programming languages they may have some of these control flow structures but they definitely have two: the if statement and the goto. Because the goto statement is strictly more powerful than these other control structures. If you have a language that doesn't support exceptions but does have a goto, then you can write an exception-like flow using goto. If you have a language that doesn't have break or continue for its loops you can build a loop that works that way using goto. If you're programming language doesn't have the broken form of case statement (that falls through to the next branch) so you can't build Duff's device [https://en.m.wikipedia.org/wiki/Duff%27s_device], then you can build that using goto.
In fact, the combination of if and goto is powerful enough to create any possible (single threaded) flow control structure including ones you and I have never even thought of.
The reason that structured programming was such an important and powerful step forward is because it made the language strictly less powerful. Because the language was less powerful, it was possible to reason more clearly about what the code could or couldn't do. In particular, it allowed a programmer to make certain assumptions about locality. If you started reading at the top of a function and worked your way down you could reason about what this function did in isolation: perhaps the tangle of loops and ifs and try-except blocks in the function are confusing, but at least you don't have to read the entire rest of the program to be certain what it is doing. With goto in your language that guarantee is gone: you might have to understand the entire rest of the program in order to figure out any one function.
So, we gave up the power to create certain flow control constructs in order to make it possible to reason about our languages. But there is nothing that says that the evolution of programming languages is finished. Exceptions are pretty nifty, and they were not part of the original toolkit. Maybe there is another control flow structure out there waiting to be discovered which is extremely useful for solving certain kinds of problems. Someone with goto in their language could discover and use that control flow structure, while those of us without goto cannot.
The same is true, to a greater degree, for function calls.
In eg. C goto:s are function scope.
If (failed) goto retry;
Is much more elegant than a loop, or at least easier to read since you only need to really pay attention to the happy path.
But you can also do that with recursion
if failed: do_thing()
This is covered in the Julia docs, where they argue recursion is more readable than goto
https://sodocumentation.net/julia-lang/topic/5564/-goto-and-...
I guess that depends on if the language supports tail recursion and/or you're 100% sure it won't blow the stack. If you need to retry forever, without using any memory to do so, goto is perfect.
Some code are more elegant to write with a goto than a loop.