How do I assign a value and get a Boolean saying whether the new value is set?
← Control Flow · Ref: Q759
In EK9 an assignment never yields a value, so the assignment and the set-check are two steps: assign with ':=', then test the target with '?'. ':=' ALWAYS evaluates the right-hand side and ALWAYS stores it - an unset result included - so afterwards the target holds exactly what was returned and 'name?' says whether it is SET. (EK9 has no '?=' operator; it was removed so that no assignment yields a value.)
ASSIGN, THEN CHECK
name as String? name := getValue() guardResult <- name?
Here guardResult is a Boolean: true if getValue() returned a set value, false otherwise. Either way name now holds what getValue() returned, so it is initialised and safe to use.
WHEN THE RHS IS UNSET
The unset value is still stored - it OVERWRITES a set target - and the check is false:
existing <- "already here" existing := getEmpty() result <- existing? // result is false, existing is now UNSET
TO KEEP AN EXISTING VALUE
If the old value must survive a missing new one, coalesce: 'existing := getEmpty() ?: existing', or fill only an unset target with ':=?' (assign-if-unset).
IN A CONTROL-FLOW HEAD
The same two steps fit in one head: 'if name := f() then name?' assigns, then runs the body only if name is now set.
See Q74 for guard variables in if. See Q77 for guard variables in while. See Q79 for the assign-if-unset :=? operator. See Q1024 for re-point-and-check in control flow.
Example
defines module qa.flow.guard.expression.boolean defines function getValue() <- rtn <- String() rtn: "hello" getEmpty() <- rtn <- String() defines program GuardExpressionBooleanDemo() stdout <- Stdout() // === ASSIGN A SET VALUE, THEN CHECK === name as String? name := getValue() guardResult <- name? stdout.println(guardResult) stdout.println(name) // === ASSIGN AN UNSET VALUE - it overwrites existing === existing <- "already here" existing := getEmpty() guardResult2 <- existing? stdout.println(guardResult2) stdout.println(existing?) stdout.println("Done")
Common mistakes
E50030 — 'name?' is a Boolean, not the type of the assigned value. Declaring the result as String triggers E50030 because Boolean and String are incompatible. Use type inference with '<-' to get the correct Boolean type. See ek9 -h E50030 for details.
Incorrect:
guardResult as String: name?
Correct:
guardResult <- name?
Other ways to ask this
- Can an assignment return a Boolean in EK9?
- Is there a ?= operator in EK9?
- How do I assign and then check isSet in one place?
Coming from another language?
Java: 'name = getValue(); boolean assigned = name != null;'. Kotlin: 'name = getValue(); val ok = name != null'. Python: 'name = getValue(); ok = name is not None'. EK9: 'name := getValue()' then 'ok <- name?' - the same two steps, and name is never a null afterwards because an unset value is still an object.
Keywords: null-safe, operator, return, conditional, assignment, isset, check, result, source, safe, guard, standalone, expression, boolean