Why doesn't EK9 have break, continue, or return statements?
← Control Flow · Ref: Q144
EK9 deliberately excludes break, continue, and return. This is not a gap or oversight. It is a core design decision backed by decades of production evidence.
THE DESIGN DECISION
EK9 removes break, continue, return, and switch fallthrough from the language grammar entirely. These keywords do not exist. The compiler cannot parse them. This eliminates an entire category of bugs at the language level rather than relying on developer discipline.
THE EVIDENCE
Microsoft (2011): 15% of production bugs in C# involved loop control flow errors with break and continue. Apple SSL bug (2014): a duplicated goto statement bypassed SSL certificate validation, affecting millions of devices. Linux Kernel: over 200 CVE fixes traced to break-in-wrong-loop and fallthrough bugs. CERT: switch fallthrough ranked as the 7th most dangerous coding error.
THE PRINCIPLE
If you eliminate a feature from the language, you eliminate every bug that feature can cause. Not reduce. Eliminate. EK9 applies this principle to the four most error-prone control flow mechanisms.
WHAT EK9 PROVIDES INSTEAD
Stream pipelines replace break and continue. Use cat, filter, head, tail, and skip to express what you want rather than how to exit:
results <- cat items | filter by isValid | head 5 | collect as List of String
Declared return variables replace return statements. The compiler verifies all paths initialise the return:
describe() as pure -> number as Integer <- label as String: "other" if number > 100 label: "high"
Multiple case values replace switch fallthrough:
switch day case "Saturday", "Sunday" type: "weekend" default type: "weekday"
Guard expressions replace early returns:
if data <- fetchData() process(data)
MODERN TRENDS
Swift removed fallthrough by default. Rust enforces exhaustive matching. Go removed fallthrough by default. Kotlin sealed classes enforce exhaustive when blocks. EK9 takes these individual improvements to their logical conclusion by removing all four mechanisms.
See Q50 for declared return variables. See Q69 for multiple case values. See Q89 for stream pipelines. See Q125 for head, tail, and skip. See Q145 for replacing break and continue. See Q146 for function decomposition. See Q147 for switch fallthrough details. See Q148 for migration control flow. See Q268 for how removing these prevents OWASP insecure design vulnerabilities. See Q274 and Q275 for AI hallucination patterns with return, break, and continue. See Q282 through Q289 for practical patterns without break, return, or continue. See Q296 for similar evidence-based naming restrictions. See Q310 for how these removals fit into the quality pyramid.
See Q338 for how no-return prevents partial transaction commits.
Example
defines module qa.flow.philosophy.overview defines function isValid() as pure -> item as String <- valid as Boolean: length item > 0 defines program NoBreakContinueReturnDemo() stdout <- Stdout() // === STREAM PIPELINE REPLACES BREAK AND CONTINUE === items <- ["apple", "", "banana", "", "cherry", "date", "elderberry"] // Filter out empty strings (replaces continue) and take first 3 (replaces break) selected <- cat items | filter by isValid | head 3 | collect as List of String stdout.println(`Selected: ${selected}`) // === DECLARED RETURN REPLACES RETURN STATEMENT === label <- describeValue(42) stdout.println(`42 is: ${label}`) label2 <- describeValue(150) stdout.println(`150 is: ${label2}`) // === MULTIPLE CASE VALUES REPLACE FALLTHROUGH === days <- ["Monday", "Saturday", "Wednesday", "Sunday"] for day in days dayType <- String() switch day case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" dayType: "weekday" case "Saturday", "Sunday" dayType: "weekend" default dayType: "unknown" stdout.println(`${day} -> ${dayType}`) defines function describeValue() as pure -> number as Integer <- label as String: "normal" upperLimit <- 100 if number > upperLimit label: "high" else if number < 0 label: "negative"
Common mistakes
E01070 — EK9 has no break statement. Stream pipelines with head replace the loop-with-break pattern. The pipeline expresses intent directly: filter and take 3. See ek9 -h E01070 for details.
Incorrect:
selected <- List() of String for item in items if isValid(item) selected += item if length selected >= 3 break
Correct:
selected <- cat items | filter by isValid | head 3 | collect as List of String
E01072 — EK9 has no return statement — it was designed out of existence. Declare a return variable with '<-' and the compiler ensures all code paths initialise it. See ek9 -h E01072 for details.
Incorrect:
<- label as String: "normal" return label
Correct:
<- label as String: "normal"
E01071 — EK9 has no continue statement. Stream pipelines with 'filter by' replace skip-and-continue patterns. The pipeline expresses filtering intent directly. See ek9 -h E01071 for details.
Incorrect:
selected <- cat items | filter by isValid | head 3 | collect as List of String continue
Correct:
selected <- cat items | filter by isValid | head 3 | collect as List of String
Other ways to ask this
- What happened to break and continue in EK9?
- Why did EK9 remove the return statement?
- Is EK9 missing break, continue, and return, or is that deliberate?
- What is the evidence against break, continue, and return?
Coming from another language?
Java: break and continue in loops, return in methods, switch fallthrough by default (arrow syntax since Java 14 avoids it). Python: break and continue in loops, return in functions, no switch until match/case in 3.10. Rust: break and continue in loops, implicit return via last expression, match is exhaustive with no fallthrough. Go: break and continue in loops, return in functions, switch has no fallthrough by default. C/C++: break and continue, return, switch fallthrough by default (major bug source). Kotlin: break and continue, return, when expression with no fallthrough. Swift: break (rarely needed), continue, return, switch with no fallthrough by default. EK9: none of these exist, replaced by stream pipelines, declared return variables, multiple case values, and guard expressions.
Keywords: cert, return, control, apple, break, condition, removed, design, microsoft, migrate, philosophy, flow, continue, safety, bug, ssl, branch, eliminate, deliberate, evidence