Do Perl loop labels count as a GOTO?

IMO, your code comparison is unfair. The goal is readable code.

To be fair, you should compare an idiomatic Perl nested loop with labels against one without them. The C style for and blocked if statement add noise that make it impossible to compare the approaches.

Labels:

OUTER: for my $wid (@ary1) {
    INNER:   for my $jet (@ary2) {
                 next OUTER if $wid > $jet;
                 $wid += $jet;
             }
       }

Without labels:

for my $wid (@ary1) {
   for my $jet (@ary2) {
       last if $wid > $jet;
       $wid += $jet;
   }
}

I prefer the labeled version because it is explicit about the effect of the condition $wid > $jet. Without labels you need to remember that last operates on the inner loop and that when the inner loop is done, we move to the next item in the outer loop. This isn't exactly rocket-science, but it is real, demonstrable, cognitive overhead. Used correctly, labels make the code more readable.

Update:

stocherilac asked what happens if you have code after the nested loop. It depends on whether you want to skip it based on the inner conditional or always execute it.

If you want to skip the code in the outer loop, the labeled code works as desired.

If you want to be sure it is executed every time, you can use a continue block.

OUTER: for my $wid (@ary1) {
    INNER:   for my $jet (@ary2) {
                 next OUTER if $wid > $jet;
                 $wid += $jet;
             }
       }
       continue {
           # This code will execute when next OUTER is called.
       }

Who cares whether it counts as goto as long as it makes the code easier to understand? Using goto can often be MORE readable than having a bunch of extra tests in if() and loop conditions.


The danger of GOTO labels is that they create spaghetti code and make the logic unreadable. Neither of those will happen in this case. There is a lot of validity in using GOTO statements, much of the defense coming from Donald Knuth [article].

Delving into the differences between your C and Perl example... If you consider what is happening at the assembly level with your C programs, it all compiles down to GOTOs anyway. And if you've done any MIPS or other assembly programming, then you've seen that most of those languages don't have any looping constructs, only conditional and unconditional branches.

In the end it comes down to readability and understandability. Both of which are helped an enormous amount by being consistent. If your company has a style guide, follow that, otherwise following the perl style guide sounds like a good idea to me. That way when other perl developers join your team in the future, they'll be able to hit the ground running and be comfortable with your code base.


Dijkstras intent was never that anything resembling goto is to be considered harmful. It was that the structure of code where gotos are used as the main construct for almost any kind of program flow change will result in what we today call spaghetti code.

You should read the original article and keep in mind that it was written in 1968 when labeled jumps was the main flow control constructs in just about all programming languages.

https://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF