What is the difference between <- and := in EK9?

← Getting Started · Ref: Q895

EK9 has THREE distinct assignment operators, each with precise semantics. Getting these wrong is one of the most common mistakes.

THREE OPERATORS

<- is DECLARATION: creates a NEW variable with its first value.
:= is ASSIGNMENT: assigns to an EXISTING variable.
:=? is GUARDED ASSIGNMENT: only assigns if the variable is currently UNSET.

RULE: Use <- exactly ONCE per variable (when you create it). Use := for all subsequent assignments.

EXAMPLES

  counter <- 0         declaration, creates counter
  counter := counter + 1   reassignment, counter already exists
  counter := 10        reassignment again

COMMON MISTAKE

Using <- when you mean to reassign:

  score <- 100         declaration — OK
  score <- 200         ERROR — score already exists, use := instead

Using := when the variable doesn't exist yet:

  total := 0           ERROR — total not declared yet, use <- instead

GUARDED ASSIGNMENT :=?

Only assigns if the variable is currently unset:

  nickname <- String()     declared but unset
  nickname :=? "Default"   assigns because nickname is unset
  nickname :=? "Other"     does NOTHING because nickname is now set

IN FUNCTIONS

<- declares the return variable:

  myFunction()
    -> inputValue as String
    <- outputResult as String: inputValue

The <- creates outputResult as the return. Any updates to it use :=

See Q22 for variable declarations. See Q93 for class definitions. See Q881 for more assignment examples.

Example

defines module qa.gettingstarted.declarevsassign

  defines function

    <?-
      Shows <- for declaration and := for reassignment.
      EK9 separates these into distinct operators.
    -?>
    countPositives() as pure
      -> numbers as List of Integer
      <- positiveCount as Integer: 0

      for n in numbers
        if n > 0
          positiveCount := positiveCount + 1

    <?-
      Shows :=? guarded assignment.
      Like Kotlin's ?: elvis operator.
    -?>
    firstNonEmpty() as pure
      ->
        primary as String
        fallback as String
      <-
        chosen as String: String()

      chosen :=? primary
      chosen :=? fallback

    <?-
      Shows all three operators in one function.
    -?>
    buildGreeting() as pure
      ->
        prefix as String
        userName as String
      <-
        greeting as String: String()

      greeting :=? prefix
      greeting :=? "Hello"

      separator <- ", "
      greeting := `${greeting}${separator}${userName}`

  defines program

    DeclarationVsAssignmentDemo()
      stdout <- Stdout()

      // <- DECLARATION: creates the variable
      score <- 100
      stdout.println(`Initial score: ${score}`)

      // := ASSIGNMENT: updates existing variable
      score := score + 50
      stdout.println(`Updated score: ${score}`)

      score := score - 20
      stdout.println(`Final score: ${score}`)

      // :=? GUARDED ASSIGNMENT: only if unset
      nickname <- String()
      nickname :=? "DefaultUser"
      stdout.println(`Nickname: ${nickname}`)

      nickname :=? "WontChange"
      stdout.println(`Still: ${nickname}`)

      // Function examples
      positives <- countPositives([3, -1, 7, -2, 5])
      stdout.println(`Positives: ${positives}`)

      chosen <- firstNonEmpty(String(), "fallback")
      stdout.println(`Chosen: ${chosen}`)

      msg <- buildGreeting("Hi", "Steve")
      stdout.println(msg)

Common mistakes

E50050 — Use ':=' to reassign an existing variable; re-using '<-' (declaration only) on the already-declared 'score' duplicates the variable. See ek9 -h E50050 for details.

Incorrect:

score <- score + 50

Correct:

score := score + 50
Other ways to ask this
  • When do I use <- vs := in EK9?
  • Why does EK9 have two assignment operators?
  • What is the declaration operator in EK9?
  • How do I reassign a variable in EK9?

Coming from another language?

Go separates declaration from reassignment with different operators — EK9 does the same with <- and :=. Python and Java use = for both (ambiguous). Kotlin uses val/var keywords. Rust uses let/let mut. EK9 uses <- to declare, := to reassign, :=? for guarded assignment.

Keywords: create, reassign, declare, assignment, variable, declaration, operator, coalesce, guard