When I was just ten years old, I ventured into the world of programming without any mentor, driven solely by the pure curiosity of a child. My companion in this adventure was my lovely MSX, which was a symbol of gaming fun back then but also a gateway to the wonderful world of programming.
In the 1980s, devices like the MSX and Commodore were primarily used for gaming, predecessors to modern consoles like today’s PlayStations. However, they also offered a Basic development environment, a programming language accessible even to novices.
In the 1980s, without access to the not-yet-popular Internet or the vast array of educational resources available today, I was able to explore this world with the limited tools available to me. One of these tools was the simple yet powerful GOTO construct.
With the Basic Programming Language, I learned programming fundamentals, moving between PRINT commands to display text on the screen, INPUT to acquire input from the user, and IF to control conditions. Then, there was GOTO, a command that allowed me to jump directly to a different instruction in the program.
The use of GOTO may seem antiquated and unorthodox to modern programmers, but it was a revelation for a young programming explorer like me. It allowed me to create loops, skip conditions, and organize my code in ways that, at the time, seemed magical.
However, over time and with more experience, I learned that abusing GOTO can lead to disorganized and hard-to-maintain code. Modern programming languages offer more sophisticated structures like for loops, conditional statements, and functions, which promote writing cleaner and more readable code.
Nevertheless, my first encounter with GOTO remains a precious memory, a symbol of my naive exploration into the world of early programming. And it’s a memory that reminds me of the importance of ingenuity and curiosity in learning new things, even when it comes to ancient programming constructs.
Why today, using GOTO is discouraged
Using goto
is discouraged in many programming languages, including PHP, due to several reasons:
-
Readability: Code that heavily relies on
goto
statements can be difficult to understand, especially for developers unfamiliar with the codebase.goto
statements can lead to spaghetti code, where the execution flow is hard to follow. -
Debugging: Debugging code that uses
goto
statements can be challenging. When the program jumps around usinggoto
, it becomes harder to trace the flow of execution and track down bugs. -
Maintainability: Code that uses
goto
statements tends to be less maintainable. If you need to modify the code later, understanding and making changes can be more difficult and error-prone. -
Structured Programming:
goto
statements can lead to unstructured code that violates the principles of structured programming. Structured programming promotes using control structures like loops and conditionals to create well-organized, easy-to-understand code. -
Scoping Issues:
goto
has limitations related to scoping. Usinggoto
to jump into a different scope (e.g., into a loop or a conditional block) can cause issues and is generally considered bad practice.
While goto
can sometimes offer a way to break out of deeply nested loops or implement specific control flow patterns, it’s often possible to achieve the same results using more structured constructs like for
, while
, foreach
, and if
statements. These constructs are more familiar to most developers and encourage writing cleaner, more maintainable code. Therefore, it’s recommended to avoid using goto except in rare cases where its benefits outweigh its drawbacks, and even then, it should be used judiciously.
“Please Don’t Try This at Home”: an example with GOTO
Now, I will show you a conversion of a PHP code snippet that uses a while loop to read and display data from a CSV file. We will use the goto
statement to replicate the loop functionality in the final code. This demonstrates how the goto
statement was used instead of the more modern loop controls. You will see how the code is less readable, difficult to understand, and difficult to debug with the goto
usage.
I will use PHP, which provides the goto
statement.
I picked “Read and print the entire contents of a CSV file” example from the PHP documentation. The code uses for
and while
statements:
<?php
$row = 1;
if (($handle = fopen("118864.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
echo "$num fields in line $row: " . PHP_EOL;
$row++;
for ($c = 0; $c < $num; $c++) {
echo " " . $data[$c] . PHP_EOL;
}
}
fclose($handle);
}
So, I think we are pretty familiar with the code above, using while
, and for.
Now let me show you the code where I will avoid using while
and for
and I will use goto
and labels:
<?php
start:
$row = 1;
if (($handle = fopen("118864.csv", "r")) === false) {
goto goodbye;
}
loop:
if (($data = fgetcsv($handle, separator:",")) === false) {
goto goodbye;
}
$num = count($data);
echo "$num fields in line $row: " . PHP_EOL;
$row++;
$c = 0;
loopLine:
if ($c >= $num) goto endLoopLine;
echo " => " . $data[$c] . PHP_EOL;
$c++;
goto loopLine;
endLoopLine:
goto loop;
closeFile:
fclose($handle);
goodbye:
echo "Goodbye";
In the provided code, labels like start
, loop
, and loopLine
are used as markers for specific points in the code’s execution flow. Here’s an explanation of their usage:
-
start
: This label marks the beginning of the code execution. It’s where the program starts its execution when it’s run. -
loop
: This label marks the start of a loop for parsing the CSV file, line by line. It’s used to indicate the point where the program should return to after completing each iteration of the loop. -
loopLine
: This label marks the inner loop within the main loop. It’s used to iterate over each file line, for parsing the fields in the current line. -
endLoopLine
: This label marks the end of the inner loop. It’s where the program jumps to after iterating over all lines in the file. -
closeFile
: This label is not used through thegoto
in the provided code. However, it could be utilized to mark the point where the file handle is closed after processing. -
goodbye
: This label marks the end of the program’s execution. It’s where the program goes if it encounters an error or reaches the end of its main logic. In this case, it prints “Goodbye”.
These labels and the goto
statements allow for a non-linear flow of control in the code. However, it’s important to note that excessive use of goto
statements and labels can make the code harder to understand and maintain. Again, it’s generally considered good practice to use more structured constructs like loops (for
, while
, foreach
) and conditional statements (if
, else
) to achieve the desired control flow whenever possible.