Observe control-flow boundaries
This recipe focuses on control transfers whose behavior is easy to misread from syntax alone. Its output records when a deferred argument is captured, whether a switch case is re-tested, and which loop a labeled branch targets.
Source
ts
import go fmt from "fmt";
function deferredEvaluation(): void {
let value = 1;
defer fmt.Print(value, " ");
value = 2;
fmt.Print(value, " ");
}
function explicitFallthrough(value: int): void {
switch (value) {
case 1 {
fmt.Print("one ");
fallthrough;
}
case 2 { fmt.Print("next "); }
default { fmt.Print("other "); }
}
}
function countVisited(): int {
let visited = 0;
outer: for (let row = 0; row < 3; row++) {
for (let column = 0; column < 3; column++) {
if (column === 1) { continue outer; }
visited++;
}
}
return visited;
}
function dispatch(ready: boolean): string {
if (ready) { goto readyPath; }
return "cold";
readyPath: return "ready";
}
function main(): void {
deferredEvaluation();
explicitFallthrough(1);
fmt.Println(countVisited(), dispatch(true));
}Run
sh
keika check control-flow-boundaries.km
keika run control-flow-boundaries.kmExpected output:
text
2 1 one next 3 readyRead the output
defer fmt.Print(value, " ")evaluatesvaluewhile it is1; changing the binding to2does not change the saved argument. The ordinary print runs first, then the deferred call runs at function exit.fallthrough;enters the following case body without testing whether itscase 2expression matches. It must be the last direct statement of a non-final value-switch case.continue outer;begins the next iteration of the named outer loop. Only column zero is counted for each of three rows.goto readyPath;transfers within one function. The checker allows this forward jump because it enters no nested block, crosses no exception boundary, and skips no declaration.
Prefer structured branches and loops for ordinary code. Labels and goto are narrow tools for making an otherwise awkward transfer explicit; the compiler rejects undefined or unused labels and unsafe jump shapes.
Read Control flow for the semantic model and the syntax reference for the complete statement forms.