What happens when I use mutating operators in EK9?
← Operators and Expressions · Ref: Q905
Mutating operators in EK9 change the object IN PLACE and return nothing (Void). Because they return nothing they are STATEMENT-ONLY: they cannot appear inside an expression.
MUTATING OPERATORS
These operators modify the object in place:
- += -= *= /= — compound arithmetic - ++ -- — increment/decrement - :=: — copy another object's value into this one (each type at its own level; a List shares its elements) - :^: — replace - :~: — merge
ALIASING
Aliasing comes from '<-', not from the operator. Declaring a variable from another variable names the SAME object, so a mutating operator through either name is seen through both:
x <- 10 y <- x x++ stdout.println(`${x} ${y}`) // prints 11 11
And 'y <- x++' does not compile at all: ++ is statement-only (E07950).
CORRECT USAGE
counter <- 0 counter++ counter += 5
// For an independent copy, construct a NEW object original <- 100 copied <- Integer(original) copied++ stdout.println(`${original} ${copied}`) // prints 100 101
NON-MUTATING OPERATORS
These create NEW objects and do NOT alias:
- + - * / — arithmetic (return new value) - == <> < > <= >= — comparison (return Boolean) - <=> — three-way compare (return Integer) - $ — string conversion (return String) - #? — hashcode (return Integer) - #^ — promote (return wider type) - ? — isSet (return Boolean)
RULE: If the operator changes the object, it is mutating and statement-only. If it produces a new value, it is non-mutating and can be used in expressions.
See Q96 for all operators. See Q238 for operator enforcement.
Example
defines module qa.operators.mutating defines function <?- Shows correct use of mutating operators as statements. ++ -- += -= are STATEMENT-ONLY, not expressions. -?> accumulateTotal() -> numbers as List of Integer <- runningTotal as Integer: 0 for n in numbers runningTotal += n <?- Shows non-mutating operators that create new values. + - * / return NEW objects, safe in expressions. -?> calculateAverage() as pure -> total as Integer divisor as Integer <- rtn as Float: 0.0 if divisor > 0 rtn := #^ total / #^ divisor defines program MutatingOperatorsDemo() stdout <- Stdout() // Mutating operators are STATEMENT-ONLY counter <- 0 counter++ counter++ counter++ stdout.println(`Counter after 3 increments: ${counter}`) counter += 10 stdout.println(`Counter after += 10: ${counter}`) counter-- stdout.println(`Counter after --: ${counter}`) // Non-mutating operators create NEW values (safe in expressions) productA <- 5 * 3 productB <- 7 + 2 stdout.println(`5 * 3 = ${productA}, 7 + 2 = ${productB}`) // <- from a variable names the SAME object, so += is seen through both names original <- 100 sharedName <- original sharedName += 50 stdout.println(`Shared: ${original}, ${sharedName}`) // An independent copy is a NEW object source <- 100 copied <- Integer(source) copied += 50 stdout.println(`Original: ${source}, Copied: ${copied}`) // Accumulation with += numbers <- [10, 20, 30, 40] total <- accumulateTotal(numbers) avg <- calculateAverage(total, length numbers) stdout.println(`Total: ${total}, Average: ${avg}`)
Common mistakes
E07950 — The ++ operator is statement-only and cannot appear inside an expression; increment first, then use the value. See ek9 -h E07950 for details.
Incorrect:
copied <- source++
Correct:
copied <- Integer(source)
Other ways to ask this
- Do mutating operators create aliases in EK9?
- What does += return in EK9?
- Why does y <- x make x and y the same object?
- How do mutating operators work in EK9?
Coming from another language?
C++: mutating operators return references (aliasing risk). Java: += modifies in place, primitives are copied but objects are aliased. Rust: no implicit aliasing — ownership system prevents it. Go: no operator overloading. Python: += modifies in place for mutable types (lists), creates new for immutable (int). EK9: mutating operators change the object in place and return nothing, so they are STATEMENT-ONLY (no 'y <- x++' puzzles); '<-' from a variable shares the object, so construct a new one (Integer(x)) when you need an independent copy.
Keywords: expression, mutating, aliasing, copy, increment, compound, decrement, statement, operator