How do I process items until a condition is met without break?
← Control Flow Without break/continue/return · Ref: Q287
In Java you write: while(true) { item = next(); if (done(item)) break; process(item); }. EK9 replaces this with guard-driven termination: the while loop condition itself controls when to stop.
THE PROBLEM
Processing items until a termination condition is the most common use of while(true) with break. The break is buried inside the loop body, making the termination condition hard to find.
PATTERN 1: WHILE WITH GUARD VARIABLE
Use a Boolean flag that controls the while loop:
done <- Boolean(false) idx <- 0 while ~done and idx < length items item <- items.getOrDefault(idx, "") if item == "STOP" done: true else process(item) idx: idx + 1
The termination condition is in the while expression, not buried in the body. Test the flag's value (~done), not whether it is set (~done?): Boolean(false) is already set, so ~done? is false and the loop would never run.
PATTERN 2: COUNTING WITH FOR-RANGE
When processing up to a known maximum:
for count in 1 ... maxItems if ~finished item <- getItem(count) if isTerminal(item) finished: true else process(item)
PATTERN 3: STREAM WITH HEAD
When you want the first N items that satisfy a condition:
results <- cat items | filter by isActive | head 10 | collect as List of String
The pipeline stops after 10 active items. No loop, no break, no counter.
GUARD-DRIVEN VS BREAK-DRIVEN
Break-driven: the loop runs forever, break is the only way out. The termination logic is scattered through the body.
Guard-driven: the while condition states exactly when the loop ends. The body focuses on processing.
See Q66 for while loops. See Q144 for no break. See Q125 for head.
Example
#!ek9 defines module qa.without.processuntil defines function isActive() as pure -> item as String <- active as Boolean: item <> "STOP" and length item > 0 processWithLimit() -> dataItems as List of String readLimit as Integer <- itemsRead as Integer: 0 for pos in 0 ... length dataItems - 1 if itemsRead < readLimit itemsRead: itemsRead + 1 defines program ProcessUntilDemo() stdout <- Stdout() // === PATTERN 1: WHILE WITH GUARD VARIABLE === items <- ["alpha", "bravo", "charlie", "STOP", "delta", "echo"] done <- Boolean(false) idx <- 0 processed <- 0 while ~done and idx < length items item <- items.getOrDefault(idx, "") if item == "STOP" done: true else stdout.println(`Processing: ${item}`) processed: processed + 1 idx: idx + 1 stdout.println(`Processed ${processed} items before STOP`) // === PATTERN 2: COUNTING WITH FOR-RANGE === numbers <- [10, 20, 30, 40, 50, 60, 70] runningTotal <- 0 totalLimit <- 100 exceeded <- Boolean(false) for count in 0 ... length numbers - 1 if ~exceeded currentNum <- numbers.getOrDefault(count, 0) if runningTotal + currentNum > totalLimit exceeded: true else runningTotal: runningTotal + currentNum stdout.println(`Running total (stopped before exceeding 100): ${runningTotal}`) // === PATTERN 3: STREAM WITH HEAD === allItems <- ["", "alpha", "bravo", "", "charlie", "STOP", "delta", "echo", "foxtrot"] activeItems <- cat allItems | filter by isActive | head 3 | collect as List of String stdout.println(`First 3 active items: ${activeItems}`) // === BOUNDED PROCESSING WITH INDEX === dataItems <- ["read1", "read2", "read3", "read4", "read5"] itemsRead <- processWithLimit(dataItems, 3) stdout.println(`Bounded read processed ${itemsRead} items`)
Common mistakes
E01070 — EK9 has no break statement. To stop processing when a condition is met, set a guard flag variable and check it in the while condition. See ek9 -h E01070 for details.
Incorrect:
break
Correct:
done: true
Other ways to ask this
- How do I replace while(true) with break-on-condition in EK9?
- How do I consume items until done without break in EK9?
- How do I write a processing loop that stops on a condition in EK9?
Coming from another language?
Java: while(true) { if (done) break; } or do-while with condition. Python: while True: if done: break. Rust: loop { if done { break; } } or while !done. Go: for { if done { break } }. Kotlin: while(true) { if (done) break }. JavaScript: while(true) { if (done) break; }. EK9: while with guard or flag variable, for-range for bounded processing, stream head for take-first-N.
Keywords: alternative, condition, consume, done, exhaust, guard, isset, loop, migrate, no-break, no-return, null-safe, process, safe, stop, terminate, until, while