Design note: why EK9 has no break, continue or return
This note goes with What's Different in
Flow Control in EK9. EK9 has no break, no continue, no
return and no switch fallthrough. They were left out on purpose, not forgotten: each one is a jump
out of the structured flow of a program, and they conflict with EK9's safety-first design.
The record
- Dijkstra (1968): "Go To Statement Considered Harmful" - jumps out of the structured flow of a program
make it hard to reason about.
break,continueand an earlyreturnare restricted forms of the same jump. - CERT C Coding Standard (MSC17-C): finish every set of statements under a case label with a
break- an omittedbreakcompiles silently and falls through (also catalogued as CWE-484, Omitted Break Statement in Switch). - Linux kernel (2019): auditing the kernel's switch statements so that
-Wimplicit-fallthroughcould be enabled found and fixed a number of missingbreakstatements (LWN.net, "An end to implicit fall-throughs in the kernel", 2019).
| Incident | Control Flow Issue | Impact |
|---|---|---|
| Apple SSL Bug (2014) | goto fail bypassed SSL certificate validation |
iOS and macOS devices vulnerable to man-in-the-middle attacks (CVE-2014-1266) |
| Linux Kernel (2017-2019) | Missing break statements in switch cases, found while marking every intended fall-through |
Latent bugs fixed, some of them years old |
The pattern: each is a jump that compiled cleanly and did the wrong thing, and each is a statement EK9 does not have.
Remove, don't warn
A warning, a coding standard or a code review asks people to avoid the mistake. Removing the statement makes the mistake impossible to write, by construction rather than by measurement:
- there is no
breakto put in the wrong loop; - cases cannot fall through, so the CERT MSC17-C / CWE-484 defect cannot be written;
- the compiler proves every path sets the returning value, so a function cannot forget to return;
- there is no
goto, so there is nogoto fail.
Swift, Go, Rust and Kotlin already have no implicit switch fallthrough. EK9 takes the idea further: if it is dangerous, it does not exist.
What you use instead
- Stream pipelines in place of
breakandcontinue:filter,skipandheadsay what you are looking for. - Guards in place of early returns.
- Several values in one case in place of fallthrough.
- A declared returning variable in place of
return, which the compiler checks on every path.
You lose no capability: each pattern you used these statements for has a more explicit replacement that the compiler can check. Flow Control in EK9 shows each one with compiled examples.
The cost
It feels restrictive at first, especially coming from Java, Python, C++ or C#. You will reach for
break or return and the compiler will stop you, with guidance under -E3.
Once you think in streams and guards, the aim is fewer bugs and faster reviews, because the control flow is
explicit and cannot be misread. The
blog article on early returns goes into the
technical detail.