If I have a String variable that might be unset, how can I conditionally assign a default value to it only when it has not been set yet?
← Operators and Expressions · Ref: Q1263
EK9 has a dedicated operator for 'assign if unset': :=? (assign-if-unset). It assigns the right-hand value to the variable ONLY if the variable is currently unset. If the variable already has a value, the assignment is silently skipped — the existing value is preserved.
THE OPERATOR
variable :=? defaultValue
WORKED EXAMPLE
greeting as String: String() // unset greeting :=? "Hello, World" // assigned, because greeting was unset stdout.println(greeting) // "Hello, World"
greeting :=? "Goodbye" // SKIPPED, because greeting is now set stdout.println(greeting) // still "Hello, World"
AFTER THE FIRST ASSIGN-IF-UNSET, THE VARIABLE IS SET AND ALL FUTURE :=? CALLS ARE NO-OPS. This is exactly what 'assign default if unset' should mean.
WHY NOT IF + ASSIGNMENT?
The long-form equivalent works but is more verbose:
if not greeting? greeting: "Hello, World"
The :=? operator collapses this into one line. It is also IMPOSSIBLE to forget the negation — there is only one direction the operator can go.
NOT TO BE CONFUSED WITH OTHER OPERATORS
- := is plain assignment (always assigns, overwrites)
- :=? is assign-if-unset (assigns only if unset)
- <- is declaration + first assignment (creates a new variable)
- <? is coalescing minimum (RETURNS the smaller value, completely different family)
See Q1264 for Integer assign-if-unset. See Q1265 for Date. See Q1266 for custom record. See Q1226 for the contrast between :=? and <?.
Example
defines module qa.operators.guardedassignstring defines function //Sourced rather than a literal, so 'title' is genuinely already-set at runtime without //the compiler being able to prove it and reject the ':=?' below as dead (E08095). loadStoredTitle() <- rtn as String: "Untitled" defines program GuardedAssignStringDemo() stdout <- Stdout() greeting as String: String() greeting :=? "Hello, World" stdout.println(`first :=? : ${greeting}`) greeting :=? "Goodbye" stdout.println(`second :=? : ${greeting}`) // Variable that already has a value at declaration title <- loadStoredTitle() title :=? "Default Title" stdout.println(`pre-set :=? : ${title}`)
Common mistakes
E08095 — :=? only assigns when the target is unset. A variable declared with a value is always set, so the compiler rejects the assign-if-unset as one that can never apply (E08095) - declare it unset, as String(), when it should take the default. See ek9 -h E08095 for details.
Incorrect:
greeting as String: "Hi"
Correct:
greeting as String: String()
Other ways to ask this
- How do I assign a default to a String only when it is unset?
- Show me the EK9 way to provide a fallback value for an unset String.
- What is the operator that assigns only when the target is unset?
- Give me a worked example of conditional default assignment on a String.
Coming from another language?
Java: if (variable == null) variable = default. Kotlin: variable = variable ?: default. Python: variable = variable or default (works but conflates falsy with None). Rust: variable = variable.unwrap_or(default). JavaScript: variable = variable ?? default (nullish coalescing assignment). EK9: variable :=? default — direct, single operator, only assigns when target is unset.
Keywords: fallback, unset, assign-if-unset, conditional assignment, default value, String, :=?