Today most languages use block structure but some have slipped the Goto back into the list of control statements - why I have no idea.
You can prove that you never need the Goto and its use is nearly always detrimental to program structure - but it's there if you really need it.
It's there as a sort of comfort blanket or perhaps for days when you want to reenact scenes from old programming practices or simply to cook up a bowl of spaghetti code to frighten the beginners.
However the Goto isn't the only bad statement prowling around.
Since the early days of structured programming language designers have tended to add structures that they think might make their languages more useful. You can now generally jump out of loops and conditionals and we have loop constructs with exit points anywhere you care to place them.
These are very capable of being misused to create spaghetti - but few are warned of the possibility.
Done properly it's great. But the need to write methods that do something coherent in terms of the object mean that methods get bigger and bigger. With structured modular programming if a procedure got bigger than ten lines of code you considered splitting it into two.
In object-oriented code you start to write an Update method and it starts to get big. What do you do split it into an Update_first and an Update_second?
You could create some private helper methods but these don't really fit with the object-oriented way of doing things. The trouble is that methods don't naturally break down in a hierarchy of procedures that have any real meaning in what the object is or does - they are simply messy internal working.
As a result object-oriented programmers don't think size matters. They often write big methods with the result that their flow of control graphs are big and messy - not quite spaghetti but well on the way to linguine.
What can you do to keep your code simple and avoid being eaten by a velociraptor?
All you really have to do is never use the Goto and aim for a simple flow of control graph.
Don't use break or continue unless it really makes your code simpler - compared to the alternatives.
Certainly never use break n or similar instructions that break out of n levels of nested structure in one jump.
Don't nest structures more than two deep unless there is some simple pattern - for example, three nested for loops are just about ok
If a section of flow of control is getting complicated break it down into methods - each method can encapsulate a part of the flow graph and make it look like uncooked spaghetti. .- i.e. straight.
If you really want to go the whole way then use some sort of complexity metric such as cyclomatic complexity - but usually this isn't necessary and is mostly a way of avoiding actually doing any programming.
Of course all rules, these and many that you no doubt can think up, are not absolute. We still have a freedom to express an algorithm as we please and the guiding principle is that the expression should indeed be pleasing.
The next time you feel like being adventurous with your code - listen for the breath of the velociraptor.
Do you manage to walk a crowded street without bumping into people or having near misses as you try to pass? If so you probably learned how to do it in a very similar way to this socially aware robot, [ ... ]