When do I use <- and when do I use :=? to set a variable safely?
← Control Flow · Ref: Q1039
They solve different problems:
<- CREATES a new variable. Use it when the variable does not exist yet.
name <- "Alice" creates name, assigns "Alice" if greeting <- getGreeting() creates greeting in this scope, only enters if SET
:=? REASSIGNS an existing variable, but only if it is currently UNSET. Use it when the variable already exists and you want to fill in a missing value without overwriting an existing one.
name <- String() creates name (unset) name :=? loadFromConfig() assigns only if name is still unset name :=? "default" assigns only if still unset after config
Key distinction:
<- is about CREATION. The variable must not exist yet. :=? is about SAFE UPDATE. The variable must already exist. It protects existing values.
Common mistake: using <- when you mean :=?
name <- loadFromConfig() WRONG if name already exists in scope name :=? loadFromConfig() RIGHT — safely fills in if unset
Common mistake: using :=? when you mean <-
name :=? "Alice" WRONG if name does not exist yet name <- "Alice" RIGHT — creates the variable
In guards (if, switch, while):
if name <- getGreeting() declaration guard — creates name, enters if SET if name :=? getGreeting() guarded assign — fills name if unset, enters if SET
Example
defines module qa.controlflow.declare.vs.guardedassign defines function loadFromConfig() <- rtn as String: String() //Simulate: config returns unset loadFromEnvironment() <- rtn as String: "env-value" defines program DeclareVsGuardedDemo() stdout <- Stdout() // <- creates a new variable setting <- String() // :=? fills in if unset (config returns unset, so still unset) setting :=? loadFromConfig() // :=? fills in from next source (environment returns "env-value") setting :=? loadFromEnvironment() // :=? preserves existing value (already set, so "fallback" is ignored) setting :=? "fallback" stdout.println(`Setting: ${setting}`) // Contrast: <- in a guard creates a NEW variable if greeting <- loadFromEnvironment() stdout.println(`Greeting: ${greeting}`)
Common mistakes
E50001 — Use <- to create a new variable; :=? only reassigns a variable that already exists, so using it first leaves the name unresolved. See ek9 -h E50001 for details.
Incorrect:
setting :=? String()
Correct:
setting <- String()
Other ways to ask this
- What is the difference between <- and :=? in EK9?
- Should I use declaration or guarded assignment here?
- How do I choose between <- for new variables and :=? for safe reassignment?
Coming from another language?
No other language has this distinction. Python's walrus := creates AND assigns. EK9 separates creation (<-) from safe update (:=?).
Keywords: declare, safe, assign, guarded, unset, create, difference