3

break interrupts a for-loop in most languages, but in the case of nested loops I have never encountered an n-th order break.
1. Is there such a thing in any language?
2. If so what is the correct name for it?
3. If not, why?
NB. I am not looking for workarounds.

Regarding point 3. The closest thing I know is goto, which should not be used as it leads to spaghetti code (Python has it only in a joke module), but this seems like a different problem as a boolean variable to mark an inner break, catching a raised a custom error or moving the block to a function in order to break with return are a lot more convoluted (in terms of line numbers and variables in the code).

(This is a curiosity question from a theoretical point of view, but if it helps, I code primarily in Python, Matlab and JS. I have know Perl, Pascal and Basic, but I know only the basics of C++ and know shamefully little of machine code.)

Matteo Ferla
  • 2,128
  • 1
  • 16
  • 27
  • After quick search I've come across those answer's in python (but I think it is applicable to other languages as well. [A1](http://stackoverflow.com/a/21293380/2377489) and [A2](http://stackoverflow.com/a/189685/2377489), basically both talking about the same thing. – quapka Apr 30 '16 at 12:15
  • 1
    "goto, which should not be used" that's debatable. the kind of spaghetti code Dijkstra had in mind was multiple entry multiple exits code blocks of that time. It's perfectly fine to use goto where it's called for, on top of structured loops of today (if, until, do, when, etc...). -- Common Lisp has named return called [`return-from`](http://clhs.lisp.se/Body/s_ret_fr.htm#return-from). – Will Ness Apr 30 '16 at 12:16
  • @WillNess. Sorry, I assumed it was one of those arguable things that had a strong consensus (_e.g._ Perl is a dead/dying language) —goto even has a ![https://xkcd.com/292/](XKCD sketch). I actually think `goto` is very handy if used properly and I really dislike the fact that Python lacks it to avoid abuse. So I am glad I was wrong. – Matteo Ferla Apr 30 '16 at 13:43
  • 1
    @MatteoFerla hey, my personal opinion is just my personal opinion! :) I saw it said like this a few times, and it makes sense to me, too. so, maybe it's better said "goto, not to be used carelessly" or something. – Will Ness Apr 30 '16 at 13:49
  • "perfectly fine to use goto where it's called for" -> the real problem Dijkstra had in mind is that everybody thinks *their* usage of goto is perfectly clear and appropriate. By removing the escape-hatch from a language altogether, though, everybody is forced to redesign their logic to be completely clean, without using nested structures requiring tangled jumping. – Alex Celeste Apr 30 '16 at 15:07
  • @Leushenko "on top of structured loops of today" i.e. where those structured constructs are inadequate and you must resort to maintaining a tangled web of "flags", one clean `goto` instead is preferable, is what I obviously meant. but YMMV. – Will Ness May 02 '16 at 21:38

6 Answers6

6

Java has a labeled break statement that lets you break out of any number of loops:

search:
    for (i = 0; i < arrayOfInts.length; i++) {
        for (j = 0; j < arrayOfInts[i].length;
             j++) {
            if (arrayOfInts[i][j] == searchfor) {
                foundIt = true;
                break search; // <<=== This statement breaks both nested loops
            }
        }
    }
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 1
    As does Javascript, and being discussed for inclusion into C. – Alex Celeste Apr 30 '16 at 12:14
  • Interesting that it is labeled —and answers my question. I would have thought a numerical argument specifying the for loops to `break` would be a solution, but I can foresee that the off-by-one problem might be an issue. Plus the `goto` label syntax (ignoring the old goto line number languages) is pre-existing. Therefore, there is nothing intrinsically wrong with a powered-up `break`, just specifying where to break becomes necessary. – Matteo Ferla Apr 30 '16 at 14:04
1

I don't know of any language that lets you do this (apart from @dasblinkenlight example - and not saying there aren't any) but you can easily emulate it in any language that has the break statement.

I.e. conditionnaly break on a boolean exit loop var.

var exitLoops = false;
for (var i = 0; i < x; i++) {
    for (var j = 0; j < y; j++) {
        for (var k = 0; k < z; k++) {
            if (something) {
                exitLoops = true;
                break;
            }
        }
        if (exitLoops) break;
    }
    if (exitLoops) break;
}
PinkTurtle
  • 6,942
  • 3
  • 25
  • 44
  • Thanks. Are you saying simply that walkarounds are easy or that the walkarounds are so simple that breaking nested loops does not warrant a specific statement? – Matteo Ferla Apr 30 '16 at 13:55
  • Honetly, I have no idea. That question should be asked to language designers/implementers. – PinkTurtle Apr 30 '16 at 16:07
1

PHP allows for "multi-level breaks" (eg. break 3 which breaks you out of three levels of loops), these are discussed here:

https://www.php.net/manual/en/control-structures.break.php

Bash also has this functionality:

https://tldp.org/LDP/abs/html/loopcontrol.html

(The term "multi-level break" appears in a 2008 article in Mathematics of Program Construction, but I don't believe this is the first appearance of the terminology: https://dl.acm.org/doi/abs/10.1007/978-3-540-70594-9_11)

Rand00
  • 376
  • 1
  • 8
0

In JavaScript you can do this

Copy paste the following the Chrome Dev Console,

free: 
for(var i=0; i<10; i++) {
  for(var j=0; j<10; j++) {
    for(var k=0;k<10;k++){
      console.log('I am at i='+i+' , j='+j+ ' , k='+k);
      if(k==3) { 
        console.log('I will now break FREE...');
        break free;
      }
    }
  }
}

console.log('... And Now I am Here...')

Output

I am at i=0 , j=0 , k=0
I am at i=0 , j=0 , k=1
I am at i=0 , j=0 , k=2
I am at i=0 , j=0 , k=3
I will now break FREE...
... And Now I am Here...
Suman Barick
  • 3,311
  • 2
  • 19
  • 31
0

There are several examples that haven't been mentioned.

Perl has a labeled break -- though Perl spells it last. The target is the name of a label at the top of the loop. For example:

#!/usr/bin/perl

use strict;
use warnings;

OUTER:
foreach my $i (1..3) {
    foreach my $j (1..3) {
        print "(i=$i j=$j) ";
        if ($i == 2 and $j == 2) {
            last OUTER;
        }
    }
    print("\n");
}
print "\n";

Ada has a similar construct, but the target is the name of the loop, which is distinct from a label that can be the target of a goto statement (and Ada spells break as exit):

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Exit_Outer is
begin
    Outer:
    for I in 1 .. 3 loop
        for J in 1 .. 3 loop
            Put("(I="); Put(I, Width => 0);
            Put(" J="); Put(J, Width => 0);
            Put(") ");
            if I = 2 and J = 2 then
                exit Outer;
            end if;
        end loop;
        New_Line;
    end loop Outer;
end Exit_Outer;
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
-1

No there isn't (as far as i know). And why ? because if you need to exit several nested for loops all at once, then you have a code design problem, not a syntax problem. all the answers given above, except of @PinkTurtle , uses some sort of goto statement , which is not recommended .

DrWael
  • 247
  • 2
  • 12