> Your language does not have that goto. Your language has a goto that has been thoroughly constrained by the structured programming paradigm. You can not goto from one function into another, in the middle of an if statement, in the middle of a for loop.
cough `longjmp()` cough. But yeah, it's not called goto...
I've never understood the hate goto gets, there are perfectly fine use cases for goto in most languages which have a goto statement. And even if one would expect otherwise most code I've seen using goto uses it in a sane way or at least intended way (that a modern language like Go can't break out of nested loops without using a label is just plain silly imho). In C there are a thousand ways you can shoot yourself in the foot, goto is nowhere near the top list.
Early on in my career as a summer intern I had to port a piece of industrial equipment code that someone new to programming had written on an Apple II over to an IBM PC infrastructure (since Apples were being discontinued.) Some features were supposed to be added to the code as part of the port.
The code was littered with gotos. Let’s say it was a 2000 line program with 100 gotos and no comments. It was very hard to follow the code flow. The “structured programming”/procedural style of naming each bit of (say) 25-50 lines of code according to its purpose and providing clear entrance and exit points was a huge advance in making code easier to work with by anyone other than its original author. Huge.
All variables were also global in those days, there were not locally scoped variables. This made gotos even worse. Reasoning about the state of a program combining global variables and lots of gotos could get quite complex for someone new working on an unfamiliar code base.
People don’t misuse goto nowdays because teachers, books, articles don’t teach it as a core primitive for flow control, due to shame. So now it’s kind of an advanced feature and not a problem. But back in the day, it made a real mess in the hands of a certain percentage of coders who invariably existed and lazily kept reusing existing lines of code, one spaghetti-mess of a goto at a time. If you’ve ever worked with someone else’s extremely/overly abstracted “DRY” code it was like that but 10x worse.
I am far from saying that code like this doesn't and didn't exist, it does and it did a lot more back in the day, absolutely. But having read my fair share of spaghetti code written by bad programmers I can also say that you don't need gotos to make code bad and unreadable. If someone doesn't know know how to properly structure code they will manage just fine without a single goto and beyond some point it doesn't matter anymore if you add goto to the recipe since it's that bad already.
You mention shame and teaching and that's a valid point historically, I was told and taught the same things and wouldn't use goto at all until I figured out (myself) that certain kinds of cleanups and control flows become much less spaghetti and more readable by using goto. Instead of shaming and teaching a silly dogma "just because" people could have taught how to use it properly in those few idiomatic use cases. It's not rocket science. It's a shame (pun slightly intended) that some code is actually less readable than it could be just because someone was taught to never use goto because it was the easier explanation. It's like lying to children because you think they can't handle an honest explanation, in almost all cases it will bite you in the ass at some point.
I think the hate for goto and the love of recursion have their origins with the ideas of the early 1970's when people like Dijkstra were obsessed with generating formal proofs from code. At the time they knew how to reason about recursion but not loops. And didn't know how to transform code with goto's.
They thought that if you banned things like loops, gotos multiple returns, etc you could produce a language suitable for 'real mathematics'. Turns out this is mostly garbage. But 50 years later it gets taught and people still believe it. People think recursion is this super duper thing when it's not. And people think multiple returns, goto, and continue statements are bad when they are fine.
While such people may exist then and now, Dijkstra was not one of them. He was not complaining about the structured control flow of modern languages (yes, C is pretty modern relative to this concern) but unstructured jumps all over the place. The issue is not multiple return but multiple entry points and multiple exit destinations. Raw machine code and assembly had no notion of procedures or functions and so many early "high-level languages" didn't either. You could jump into the same chunk of code at different places and then jump back out of it to yet more random places. This was even seen as a feature by some because it enabled more aggressive code reuse. But the code quickly became unreadable and following the control flow through the code could become nigh-on impossible (the original "spaghetti code" which really could go from anywhere to anywhere at just about any time). This led to many subtle bugs which also in practice made the pieces of code less reusable since weaving through the code so much often picked up side-effects from its many different purposes. The use of structured procedures with a single entry point and well defined exit behavior (which we now call "return" because you exit back to the same place you came from every time) is what Dijkstra wanted, and he was right. It has become so well accepted that people don't even understand what he was complaining about because modern languages don't allow it.
The arguments I've heard are basically increased cognitive load and the ability to make spaghetti logic. There may also be some concern, depending on the language, that problems are more likely if you can arbitrarily exit a scope/context without cleanup steps you might be counting on.
IMHO, I believe the reasoning behind "exceptions are bad" comes from a similar place.
cough `longjmp()` cough. But yeah, it's not called goto...
I've never understood the hate goto gets, there are perfectly fine use cases for goto in most languages which have a goto statement. And even if one would expect otherwise most code I've seen using goto uses it in a sane way or at least intended way (that a modern language like Go can't break out of nested loops without using a label is just plain silly imho). In C there are a thousand ways you can shoot yourself in the foot, goto is nowhere near the top list.