E08120: mutating variables is not allowed when scope is marked as 'pure'
What went wrong
You're calling a MUTATING operation (like +=, :=:, ++, --) inside a PURE context where mutations are forbidden.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 54 (What are pure functions and what is the difference betwee...)
- ek9 -q 273 (How does purity create security boundaries?)
- ek9 -q 52 (What are dynamic functions and how do they differ from la...)
- ek9 -q 53 (How do closures and variable capture work in EK9?)
- ek9 -q 268 (How does EK9 prevent common security vulnerabilities?)
Mutating operators
'++', '--', '+=', '-=', '*=', '/=', ':=:', ':~:', ':^:'
How to fix it
- Use non-mutating alternatives (+ instead of +=)
- Create new values instead of mutating
- If mutation needed, remove 'pure' modifier
Common causes
- Using compound assignment in pure function
- Calling mutating method in pure scope
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E08120: mutating variables is not allowed when scope is marked as 'pure'
#!ek9 defines module error.e08120.bad defines function withReviewedTag() as pure -> tags as List of String <- tagged as List of String: tags tags += "reviewed"
Fixed: Return a new value instead of changing one
#!ek9 defines module error.e08120.good defines function withReviewedTag() as pure -> tags as List of String <- tagged as List of String: tags + "reviewed"
Questions and answers
These Q&A entries show E08120 and its fix:
- Q52: What are dynamic functions and how do they differ from lambdas?
- Q53: How do closures and variable capture work in EK9?
- Q54: What are pure functions and what is the difference between Consumer and Acceptor?
- Q268: How does EK9 prevent common security vulnerabilities?
- Q272: How do I build defense in depth in EK9?
- Q273: How does purity create security boundaries?
- Q560: What does 'as pure' mean on a method in EK9?
- Q589: How do I implement an abstract function with multiple implementations?
- Q590: Can dynamic functions extend abstract functions?
- Q592: What happens if a function extension has a signature mismatch?
- Q593: Can functions form multi-level inheritance chains?
- Q594: What are the rules for when a function can or cannot be extended?
- Q595: How does purity interact with abstract function extension?
- Q600: How does method overloading work compared to function dispatching?
- Q635: What operations are forbidden inside a pure method?
- Q690: How do pure function call chains work and what restrictions apply?
- Q790: Why can't I reassign variables in a pure function?
- Q1109: Mutate a Counter component's state through increment and reset methods.
- Q2000: If a parameter cannot be reassigned, is it read-only? How do aliasing and copying work in EK9?