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 (+=, -=, *=, /=, :=:, :~:, :^:). Inside a pure scope only the declared return variable may be assigned again; any other variable is declared once with '<-' (or assigned only-if-unset with ':=?'), and reassigning it with ':' or ':=' is E08100. 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
Assigning the return variable (rtn: working + 1). Declaring new locals with '<-'. Creating new values with non-mutating operators (+, -, *, /). Reading fields and parameters. Returning computed values.
WHAT PURE FORBIDS
Mutation operators (+=, -=, *=, /=, :=:, :~:, :^:) are forbidden (E08120), even on the return variable. Reassigning any variable other than the return variable with ':' or ':=' is forbidden (E08100). 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 method may assign its own return variable, but no other variable; //a local is declared once with '<-' and never reassigned offsetBy() as pure -> inputValue as Integer <- rtn as Integer: 0 working <- inputValue * factor rtn: working + 1 //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}`) stdout.println(`3 * 10 + 1 = ${calc.offsetBy(10)}`) //Non-pure: mutates factor calc.adjustFactor(2) stdout.println(`After adjust: ${calc.currentFactor()}`) result2 <- calc.compute(10) stdout.println(`5 * 10 = ${result2}`)
Common mistakes
E08100 — In a pure method only the declared return variable may be assigned again. Reassigning the local 'working' is E08100; compute into the return variable instead (or declare a new local with '<-'). See ek9 -h E08100 for details.
Incorrect:
working: working + 1
Correct:
rtn: working + 1
E08120 — Mutation operators such as '+=' are forbidden in a pure scope, even on the return variable. Assign a newly computed value with ':' instead. See ek9 -h E08120 for details.
Incorrect:
rtn += working + 1
Correct:
rtn: working + 1
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, no reassignment except of the return variable, and no non-pure calls at compile time.
Keywords: contract, immutable, mutation, purity, side-effect, pure, method, enforce, operator