C89-Goto: Thoughts
If there is something close to religion in programming, it probably involves the goto
statement. A scarcely yielded but very powerful tool in the hands of a skilled programmer, or absolute blasphemy in acedemia. Regardless of what one believes, I think it's crucial to understand the goto
statement in order to understand execution flow of an application.
Goto considered harmful
The history behind why goto
is considered harmful is due to the nature of implementations in old languages. In modern languages, goto
is restricted to function it's executed in (a short jump). However, in older languages goto
was able to jump outside these bounds into a completely different part of the application (a long jump).
With programming languages evolving rapidly in the 1970s, Edsger W. Dijkstra made the case in a public letter that alternatives to goto
should be preferred when available to denote more specifically what was going on, and that there is rarely a case where goto
should be used.
Sadly, people (mostly acedemia) took his message out of context and dogmatically believed that goto
should never be used, even at the detriment of the code's quality. Donald E. Knuth wrote in response a publication which highlights more in-depth where goto should and shouldn't be used, as well as the loss of quality when other control structures are used incorrectly to avoid goto
usage.
The result is that the next 20 years programming language would opt for adding goto
with short-jump functionality instead of long-jump, and starting around 2000 new languages would opt for excluding goto entirely, replacing it with labled breaks and newer inventions like exceptions to reduce the need for goto tremendously.
What was lost
There is something which saddens me to see as a self-proclaimed programming language linguist: the simplicity of a language. One can emulate almost every control structure in existance (excluding if
and maybe something very exotic that I'm not aware of) with the goto
statement.
This means that we would only need primitive data types (int
, short
, etc), struct
, arrays, (function) pointers, malloc
and free
, if
, else
, return
, and goto
to have a language capable enough to express all code structures a "modern" programming language (rust, go, java, C#) includes.
This means we wouldn't need while
, do-while
, for
, foreach
, break
, continue
, switch-case
and the likes to clutter the language, all of it can be expressed with goto
.
Sure it might not look the same, but I wouldn't say it would necessarily be worse since we're very explicit about execution flow. It takes a different mindset than what most are being taught; how to think like a computer.
Because the goto
statement is no longer taught today, most people don't know how to use it, when to use it and why to use it. And thus people are dreaded by encountering the statement, declaring it a "bad code practice". And since we live in the world of "best code pratices" and "standards", it is the worst insult a statement can get and thus it gets avoided at all cost.
Programmers no longer research why things are the way they are.
So, what now?
For educational and archiving purposes I'll talk in this series of articles about how goto can be used to emulate existing control structures, as well an example of where goto
can still be used today. Hopefully this will spread more (positive) awareness of how the goto
statement can be utilized.