Are collections mutable or immutable in EK9?
← Collections and Data Structures · Ref: Q130
EK9 collections are mutable by default. The language distinguishes between mutating operators (modify in place) and non-mutating operators (create new copies).
MUTATING OPERATORS
These modify the collection in place:
list += item appends item to this list list -= item removes item from this list dict += entry adds entry to this dict dict -= key removes key from this dict
The original collection is changed.
NON-MUTATING OPERATORS
These create new collections, leaving the original unchanged:
newList <- list + item new list with item appended newList <- list - item new list without item newDict <- dict + entry new dict with entry added
The original collection is not modified.
WHEN TO USE EACH
Mutating (+=, -=): building up a collection step by step, performance-sensitive code.
Non-mutating (+, -): functional style, preserving original data, pipeline transforms.
PURE FUNCTIONS AND COLLECTIONS
Pure functions cannot mutate their parameters. If a pure function receives a collection, it can only use non-mutating operators:
process() as pure -> items as List of String <- rtn as List of String: items + "extra"
The + operator creates a new list. The original items list is untouched.
See Q45 for List basics. See Q88 for List operations. See Q54 for pure functions. See Q96 for operator overloading. See Q122 for collect as aggregation with operator |. See Q128 for why collection types are closed. See Q141 for constant immutability and copy-on-access protection.
Example
defines module qa.collections.mutableimmutable defines function addSuffix() as pure -> items as List of String suffix as String <- rtn as List of String: items + suffix defines program MutableImmutableDemo() stdout <- Stdout() // === MUTATING: += MODIFIES IN PLACE === fruits <- List() of String fruits += "apple" fruits += "banana" fruits += "cherry" stdout.println(`After +=: ${fruits}`) // === NON-MUTATING: + CREATES NEW === moreFruits <- fruits + "date" stdout.println(`Original: ${fruits}`) stdout.println(`New list: ${moreFruits}`) // === MUTATING: -= REMOVES IN PLACE === fruits -= "banana" stdout.println(`After -=: ${fruits}`) // === NON-MUTATING: - CREATES NEW === lessFruits <- fruits - "cherry" stdout.println(`Original: ${fruits}`) stdout.println(`Without cherry: ${lessFruits}`) // === DICT MUTATING === config <- {"host": "localhost"} config += DictEntry("port", "8080") stdout.println(`Config: ${config}`) // === PURE FUNCTION WITH COLLECTION === result <- addSuffix(fruits, "!") stdout.println(`Pure result: ${result}`) stdout.println(`Original unchanged: ${fruits}`)
Common mistakes
E50060 — EK9 uses the += operator to add items to a list, not an add() method. The operator syntax is consistent across all collection types. See ek9 -h E50060 for details.
Incorrect:
fruits.add("apple")
Correct:
fruits += "apple"
E50060 — EK9 uses the -= operator to remove items from a list, not a remove() method. See ek9 -h E50060 for details.
Incorrect:
fruits.remove("banana")
Correct:
fruits -= "banana"
E50060 — EK9 List has no append() method. Use the += operator to add items. EK9 uses consistent operator syntax across all collection types rather than named methods. See ek9 -h E50060 for details.
Incorrect:
fruits.append("cherry")
Correct:
fruits += "cherry"
E50060 — EK9 Dict has no put() method. Use the += operator with DictEntry to add entries. See ek9 -h E50060 for details.
Incorrect:
config.put("port", "8080")
Correct:
config += DictEntry("port", "8080")
Other ways to ask this
- How do mutating and non-mutating operators differ on EK9 collections?
- Can I modify a list in place in EK9?
- What is the difference between += and + for lists in EK9?
Coming from another language?
Java: Collections.unmodifiableList() for immutable wrappers, List.of() for immutable since Java 9, ArrayList mutable. Python: lists mutable, tuples immutable, frozenset immutable. JavaScript: no built-in immutable, use spread [...arr, item] or Object.freeze(). Rust: Vec mutable by default, shared references prevent mutation. Go: slices mutable, no immutable variant. EK9: collections mutable by default, += mutates, + creates new, pure functions enforce read-only through language rules.
Keywords: side-effect, modify, plus, data-structure, copy, collection, immutable, operator, list, pure, minus, mutating, mutable