How do I exit a nested loop without break or labels?
← Control Flow Without break/continue/return · Ref: Q282
EK9 has no break, no labels, and no goto. When you need to exit nested loops, the solution is function decomposition: extract the inner loop into its own function.
THE PROBLEM
In Java you write: outer: for (row : grid) { for (item : row) { if (found(item)) break outer; } }. In Python you use flag variables or exceptions. These patterns are error-prone and obscure intent.
PATTERN 1: DECOMPOSE INTO FUNCTIONS
Extract the inner loop into a separate function that returns unset if nothing found:
searchRow()
-> row as List of String, target as String
<- found as String: String()
for item in row
if item == target
found: item
Then guard on the result in the outer loop:
for row in grid if match <- searchRow(row, target) result: match
The outer loop naturally stops assigning once result is set, and the inner function handles one level of nesting.
PATTERN 2: FLATTEN AND STREAM
For simple search across nested data, flatten with concatenation and use filter + head:
allItems <- cat row1 + row2 + row3 | filter by isTarget | head 1 | collect as List of String
This avoids nested loops entirely by working with a flat pipeline.
PATTERN 3: WHILE WITH GUARD
Use a flag to control the outer loop:
located <- Boolean() rowIndex <- 0 while rowIndex < length grid and ~located? row <- grid.getOrDefault(rowIndex, List() of String) for item in row if item == target located: true rowIndex: rowIndex + 1
The while loop exits when located becomes set.
KEY PRINCIPLE
If you need nested break, your function is doing too much. Decompose it. Each function handles one level of iteration.
See Q144 for why break was removed. See Q145 for basic break replacement. See Q146 for function decomposition.
Example
defines module qa.without.nestedloop defines function searchRow() -> row as List of String target as String <- found as String: String() for item in row if item == target found: item isMatch() as pure -> item as String <- matched as Boolean: item == "cherry" defines program NestedLoopDemo() stdout <- Stdout() // === PATTERN 1: DECOMPOSE INTO FUNCTIONS === row1 <- ["apple", "banana", "cherry"] row2 <- ["date", "elderberry", "fig"] row3 <- ["grape", "honeydew", "kiwi"] grid <- [row1, row2, row3] target <- "cherry" result <- String() for row in grid if match <- searchRow(row, target) result :=? match if result? stdout.println(`Found by decomposition: ${result}`) else stdout.println("Not found by decomposition") // === PATTERN 2: FLATTEN AND STREAM === allItems <- row1 + row2 + row3 streamResult <- cat allItems | filter by isMatch | head 1 | collect as List of String stdout.println(`Found by stream: ${streamResult}`) // === PATTERN 3: WHILE WITH GUARD === located <- Boolean() rowIndex <- 0 while rowIndex < length grid and ~located? row <- grid.getOrDefault(rowIndex, List() of String) for item in row if item == target located: true rowIndex: rowIndex + 1 stdout.println(`Located by while: ${located?}`) // === SEARCH FOR MISSING ITEM === missing <- String() for row in grid if match <- searchRow(row, "mango") missing :=? match if ~missing? stdout.println("Mango not found as expected")
Common mistakes
E01070 — EK9 has no break statement. To exit a nested loop, decompose into functions and use guard assignment (:=?) so the first successful result wins. See ek9 -h E01070 for details.
Incorrect:
break
Correct:
result :=? match
Other ways to ask this
- How do I stop both inner and outer loops without break in EK9?
- What replaces labelled break for nested loops in EK9?
- How do I search a grid or matrix without break in EK9?
Coming from another language?
Java: break with label (break outer;) for nested loops. Python: flag variables or raise/except hack. Rust: break with loop labels ('outer: loop { break 'outer; }). Go: break with label, or goto. C/C++: goto or flag variables. Kotlin: break with label (@outer). JavaScript: break with label. EK9: decompose inner loop into a function, guard on result, or flatten and stream.
Keywords: label, no-return, inner, nested, break, loop, grid, decompose, alternative, matrix, migrate, exit, outer, search, no-break, function, flatten