Can I use a guard (including '?=') inside a switch or loop expression in EK9?
← Control Flow · Ref: Q837
Yes. A body-skipping guard ('<-' declaration, '?=' guarded assignment, ':=?' assign-if-unset) works in an expression-form switch/for/while/do-while/try, just as in statement form. The guard gates the whole construct: if the guarded value is unset the body is skipped, and the left-hand side takes the returning variable's INITIAL value - 'the initialiser is the guard's else'.
BECAUSE OF THAT, THE RETURN MUST BE INITIALISED
Declare the return with an initial value ('<- rtn as T: default'). If you declare it uninitialised ('<- rtn as T?') and set it only inside the (skippable) body, the compiler rejects it with E08050 RETURN_NOT_ALWAYS_INITIALISED, because the skip path would leave the LHS unset.
THIS EXAMPLE
A switch expression with a '?=' guard and an initialised return. The guard sets 'temperature', the switch runs, and 'resultText' gets a case value; had the guard left 'temperature' unset, 'resultText' would be the initial "Unknown".
See Q759 for guard patterns. See Q69 for multi-case switch.
Example
defines module qa.controlflow.guard.expression defines function currentTemperature() as pure -> country as String <- temperature as Integer? if country == "GB" temperature :=? 18 else if country == "DE" temperature :=? 35 else temperature :=? 25 defines program GuardDemo() stdout <- Stdout() //Valid: a '?=' guard in a switch expression. The guard gates the switch; if 'temperature' were left //unset the body would be skipped and 'resultText' would take the return's initial value ("Unknown"). temperature as Integer? resultText <- switch temperature ?= currentTemperature("GB") with temperature <- result as String: "Unknown" case < 12 result: "Cold" case < 25 result: "Moderate" default result: "Warm" stdout.println(resultText)
Common mistakes
E08050 — In an expression form, a guard can skip the body, so the return must be initialised at declaration. Give it a default ('<- result as String: "Unknown"'); an uninitialised '<- result as String?' set only in the body is E08050 RETURN_NOT_ALWAYS_INITIALISED.
Incorrect:
<- result as String?
Correct:
<- result as String: "Unknown"
Other ways to ask this
- Do guards work in switch/for/while/try expressions?
- What does 'result <- switch temp ?= getValue() with temp' do?
- Why does a guard in an expression need an initialised return (E08050)?
Coming from another language?
Kotlin 'when' and Rust 'match' are expressions but have no guard-gating pre-flow. EK9 unifies it: the same guard syntax works in statement AND expression forms, and the mandatory return initialiser is the value the LHS receives when the guard skips.
Keywords: conditional, switch, E08050, guarded assignment, expression, initialised return, guard