5

Situation: You have a nested loop, and you need to break out of it.

Let's take this classic example (classic because it came from Goto Considered Harmful Considered Harmful): Given a 2-dimensional NxN square integer matrix X, find the first row with no zeroes.

I'll go through a few ways that different languages would solve this. I suppose I should start with how it could be written, but isn't.

//using "chained breaks"
for(int i=0;i<N;i++){
    for(int j=0;j<N;j++){
        if( X[i][j] == 0 ){
            //this row isn't non-zero, so go to the next row
            break continue;
                //break out of the inner loop and continue the outer loop
        }
    }
    //if we get to here, we know this row doesn't have zeroes
    return i;
}
return -1; //failure; exact val doesn't matter for this question

C and its mostly-faithful derivatives:

//goto
for(int i=0;i<N;i++){
    for(int j=0;j<N;j++){
        if( X[i][j] == 0 ){
            //this row isn't non-zero, so go to the next row
            goto next; //skip past the return
        }
    }
    //if we get to here, we know this row doesn't have zeroes
    return i;
    label next;
}
return -1; //failure; exact val doesn't matter for this question

Java:

//labeled loops and labeled break/continue
outer: for(int i=0;i<N;i++){
    for(int j=0;j<N;j++){
        if( X[i][j] == 0 ){
            //this row isn't non-zero, so go to the next row
            continue outer; //go to the next row
        }
    }
    //if we get to here, we know this row doesn't have zeroes
    return i;
}
return -1; //failure; exact val doesn't matter for this question

PHP:

//this PHP may be wrong, it's been a while
for($i=0;$i<$N;$i++){
    for($j=0;$j<$N;$j++){
        if( $X[$i][$j] == 0 ){
            //this row isn't non-zero, so go to the next row
            continue 2;
                //continue the outer loop
        }
    }
    //if we get to here, we know this row doesn't have zeroes
    return $i;
}
return -1; //failure; exact val doesn't matter for this question

Using a flag:

//using a flag
for(int i=0;i<N;i++){
    bool foundzero = false;
    for(int j=0;j<N;j++){
        if( X[i][j] == 0 ){
            //this row isn't non-zero, so go to the next row
            foundzero = true;
            break; //go to the next row
        }
    }
    //if we get to here, we know this row doesn't have zeroes
    if(!foundzero)
        return i;
}
return -1; //failure; exact val doesn't matter for this question

Exporting the inner loop to a function:

//using a function call
for(int i=0;i<N;i++){
    if(haszero(X[i],N))
        return i;
}
return -1; //failure; exact val doesn't matter for this question

//and the haszero function
bool haszero(int arr[], int N){
    for(int i=0;i<N;i++){
        if( arr[i] == 0 ){
            return false;
        }
    }
    return true;
}

Now, all of these work, but some with function call overhead (bad if the language wants to allow for deep loops), flags (distasteful or unintuitive for some), goto (more powerful than you might need),or weird syntax (Java's silliness).

So why don't languages have break break, break continue, break break continue, etc.? (continue break makes little sense to no sense, as it means to go to the next iteration and then leave it). Are there problems with adding this sort of thing to the language?

Guillermo Gutiérrez
  • 17,273
  • 17
  • 89
  • 116
leewz
  • 3,201
  • 1
  • 18
  • 38
  • Probably because of the extremely small number of registers that computers have; historically it would have been difficult to keep enough registers available to support your suggestion. – Elliott Frisch Dec 31 '13 at 05:53
  • 1
    If a language supports `break break`, then it should probably support N nested loops (`break break break`, `break break break break`, etc). – Alon Gubkin Dec 31 '13 at 05:57
  • I can't see a reason why this doesn't already exist, it would be easy to implement something very similar as a desugarizer or during preprocessing. And it would add even better abstraction for further features... – randomusername Dec 31 '13 at 05:57
  • I may very well try and have this incorporated into the GCC... Thank you for the idea – randomusername Dec 31 '13 at 05:59
  • 2
    @ElliotFrisch Registers have nothing to do with it. It all happens at compile time. The only instructions that need to be emitted are, possibly, a stack pop, and a jump. However the only possible answer to the question is "because they didn't". – user207421 Dec 31 '13 at 05:59
  • 2
    Goto by any other name is still a goto... Using break and continue without labels and return before the last statement of a function enable most use cases for which purely structural syntax would be needlessly complex without falling off the edge of the structured programming world into the dreaded spaghetti bowl of goto Hell! – Ned Dec 31 '13 at 06:01
  • A single statement to perform a controlled exit out of multiple levels of loop blocks would be intrinsically difficult to maintain if one of the (perhaps distant) outer loop structures is changed later on. In other words, as Ned implied, it's really no better than a goto statement. Explicit named flags, while seemingly less graceful, are easier to track than block structure. – Mike Woolf Dec 31 '13 at 06:31
  • But "Are there problems with adding this sort of thing to [a] language?" – leewz Dec 31 '13 at 08:05
  • 1
    @leewangzhong No, but it's a poor idea. The labelled 'break' is a much better alternative, as it doesn't rely on the current nesting level, and therefore doesn't have to be changed if the nesting level changes. – user207421 Dec 31 '13 at 08:51
  • I disagree with the "opinion" complaint. I'm asking for concerns with adding such a thing to a language, not whether it's better or worse than the alternatives. – leewz Jan 02 '14 at 04:24
  • I guess that PHP implementation is the most reasonable and sensible way. – Guillermo Gutiérrez Jan 02 '14 at 19:46
  • @leewangzhong 'Opinion-based' refers to the question expressed in your title. If that doesn't reflect your actual question, whose fault is that? – user207421 Jan 02 '14 at 21:49
  • "Why not"? "What reasons are there for this not to be the case?" Not "Should this be the case?" – leewz Jan 02 '14 at 23:06

0 Answers0