What does 'as pure' mean on a method in EK9?
← Purity Contracts · Ref: Q560
The 'as pure' modifier on a method guarantees that it will not mutate any state through mutation operators. This is a compiler-enforced contract, not a convention.
WHAT PURE MEANS
A pure method cannot use mutation operators (+=, -=, *=, /=, :=:, :~:, :^:). It can reassign local variables with : (which creates a new value). It cannot call non-pure methods. The compiler enforces all of these rules.
HOW TO DECLARE PURE
Add 'as pure' after the method name:
calculate() as pure -> x as Integer <- rtn as Integer: x + 1
WHAT PURE ALLOWS
Reassignment with : (creates new binding, not mutation). Creating new values with non-mutating operators (+, -, *, /). Reading fields and parameters. Returning computed values.
WHAT PURE FORBIDS
Mutation operators (+=, -=, *=, /=, :=:, :~:, :^:) are forbidden (E08120). Calling non-pure functions or methods is forbidden (E08130). These are compile-time errors, not runtime checks.
WHY PURE MATTERS
Pure methods are safe to call from any context. They cannot corrupt shared state. They enable compiler optimizations. They create auditable security boundaries.
See Q273 for purity as a security boundary. See Q54 for pure functions and Consumer vs Acceptor. See Q561 for purity inheritance rules. See Q566 for pure call chain restrictions. See Q612 for dispatcher purity matching requirements. See Q635 for forbidden mutation operators in pure methods.
See Q666 for injection in pure context.
See Q678 for purity override contract. See Q690 for pure call chain.
Example
defines module qa.purity.basics defines class Calculator factor <- 1 Calculator() -> factor as Integer this.factor: factor //A pure method: no mutation, just computation compute() as pure -> inputValue as Integer <- result as Integer: inputValue * factor //A pure accessor: reads state without modifying it currentFactor() as pure <- rtn as Integer: factor //Non-pure method: uses mutation operator adjustFactor() -> delta as Integer factor += delta default operator ? defines program PureMethodBasicsDemo() stdout <- Stdout() calc <- Calculator(3) stdout.println(`Factor: ${calc.currentFactor()}`) result <- calc.compute(10) stdout.println(`3 * 10 = ${result}`) //Non-pure: mutates factor calc.adjustFactor(2) stdout.println(`After adjust: ${calc.currentFactor()}`) result2 <- calc.compute(10) stdout.println(`5 * 10 = ${result2}`)
Common mistakes
E50001 — Renaming the variable means later references to 'calc' become unresolved, triggering E50001. See ek9 -h E50001 for details.
Incorrect:
calcXYZ <- Calculator(3)
Correct:
calc <- Calculator(3)
E50001 — Renaming the variable means later references to 'result' become unresolved, triggering E50001. See ek9 -h E50001 for details.
Incorrect:
resultXYZ <- calc.compute(10)
Correct:
result <- calc.compute(10)
Other ways to ask this
- How do I mark a method as pure in EK9?
- What restrictions apply to pure methods?
- How does EK9 enforce method purity?
Coming from another language?
Java: no purity concept, any method can mutate anything. Python: no purity enforcement. Haskell: all functions pure by default (IO monad for effects). Rust: immutable borrows prevent mutation but no purity marker. Kotlin: no purity concept. EK9: 'as pure' modifier enforces no mutation operators and no non-pure calls at compile time.
Keywords: mutation, immutable, contract, operator, enforce, method, pure, side-effect, purity