Why does EK9 separate variable declaration from assignment?
← Getting Started · Ref: Q968
EK9 separates declaration (<-) from assignment (:=) to prevent accidental variable creation and make variable lifetimes explicit.
THE PROBLEM IN OTHER LANGUAGES:
In Python/JavaScript, x = 5 either creates or reassigns — you can't tell which. This leads to:
- Accidental shadowing (creating a new variable when you meant to update)
- Typo bugs (misspelling a variable name creates a new one silently)
- Unclear lifetime (when was this variable created?)
EK9'S SOLUTION:
<- means 'I am creating something new' := means 'I am updating something that exists'
This makes every variable's birth point explicit in the code.
Many languages (Go, Rust, Ada) also separate declaration from assignment. EK9 uses <- for new variables and := for updates — making every variable's birth point visible in the code.
See Q965 for the full assignment operator guide.
Example
defines module qa.gettingstarted.declvsassign defines function <?- Shows the lifecycle: declare with <-, update with :=. EK9 separates declaration (<-) from assignment (:=). -?> buildGreeting() -> firstName as String lastName as String <- rtn as String: String() // <- creates the variable (declaration) fullName <- `${firstName} ${lastName}` // := updates the variable (assignment to existing variable) fullName := `${fullName}!` rtn := fullName defines program DeclVsAssignDemo() stdout <- Stdout() // <- declares new variables message <- buildGreeting("Steve", "Limb") stdout.println(message) // := updates existing variable message := buildGreeting("Alice", "Smith") stdout.println(message) // :=? only assigns if currently unset optionalName <- String() optionalName :=? "Fallback" stdout.println(`Optional: ${optionalName}`) // :=? has no effect when already set optionalName :=? "Ignored" stdout.println(`Still: ${optionalName}`)
Common mistakes
E50001 — The first use of a variable must declare it with '<-'; using ':=' on 'message' before it exists means the name does not resolve. See ek9 -h E50001 for details.
Incorrect:
message := buildGreeting("Steve", "Limb")
Correct:
message <- buildGreeting("Steve", "Limb")
Other ways to ask this
- Why can't I just use = for everything in EK9?
- What's the point of having <- and := as separate operators?
- Why does EK9 force me to use <- the first time?
- How is <- different from := in practice?
Coming from another language?
Go separates declaration from reassignment with different operators, just like EK9. Rust uses 'let' keyword for declaration. Python and Java use = for everything. EK9 makes the distinction at the operator level: <- for new, := for update.
Keywords: lifetime, assignment, variable creation, shadowing, declaration