What is the difference between <-, :=, and :=: in EK9?
← Getting Started · Ref: Q879
Three operators, three purposes:
other <- String() name <- "Steve" // DECLARE: creates new variable, type inferred other :=: name // COPY: copies the value of name into the existing object other name := "Different" // ASSIGN: changes existing variable
Think of it this way:
- '<-' is for BIRTH — the variable didn't exist before this line
- ':=' is for CHANGE — the variable already exists, you're updating it
- ':=:' is for COPYING — copy the contents into an existing object, not the reference. Each type copies at its own level: a List copies its element references (the elements are shared), and the generated default :=: is shallow - each field then refers to the source's object; write your own :=: for a deeper copy (Q2100).
There are also conditional variants:
config <- String() config :=? "default" // assign only if config is currently UNSET
if value <- getValue() // guard that DECLARES: the block runs only if the result is SET stdout.println(value)
current <- String() if current := getValue() then current? // EXISTING variable: assign, then run the block only if SET stdout.println(current)
Common mistake from Java/Python developers: using '<-' to reassign. A second '<-' on a name that already exists, in the same scope or a nested block, is compile error E50050 (Variable/Constant duplicated) - nothing is shadowed. Use ':=' to change an existing variable.
See Q22 for variable declaration. See Q29 for unset variables. See Q75 for guards.
Example
defines module qa.getting.started.three.operators defines program ThreeOperators() stdout <- Stdout() //DECLARE with <- counter <- 0 stdout.println(`Created counter: ${counter}`) //ASSIGN with := counter := 10 stdout.println(`Changed counter: ${counter}`) //COPY with :=: backup <- 0 backup :=: counter counter := 99 stdout.println(`Counter now: ${counter}`) stdout.println(`Backup is still: ${backup}`) //CONDITIONAL with :=? serverName <- String() serverName :=? "localhost" stdout.println(`Server: ${serverName}`)
Common mistakes
E50050 — counter already exists, so a second '<-' is E50050 (Variable/Constant duplicated) - EK9 does not shadow. Use ':=' to change an existing variable. See ek9 -h E50050 for details.
Incorrect:
counter <- 10
Correct:
counter := 10
Other ways to ask this
- EK9 has too many assignment operators — which one do I use?
- When do I use := vs :=: vs <- in EK9?
- Explain the arrow and colon operators in EK9
Coming from another language?
Java: single '=' for everything. Python: single '=' for everything. Rust: 'let' for declare, '=' for assign. EK9: '<-' declare, ':=' assign, ':=:' copy into an existing object (each type at its own level) — each has distinct semantics. Re-declaring with '<-' is an error (E50050), never shadowing.
Keywords: colon, assign, operator, copy, arrow, declare, variable, difference