Why can't I call a non-pure function from a pure function?
← Purity Contracts · Ref: Q791
A pure function can only call other pure functions and methods. Calling a non-pure function would allow side effects to leak into the pure context, breaking the purity guarantee.
THE PURITY CHAIN
If A is pure and calls B, then B must also be pure. If B calls C, then C must be pure too. The entire call chain from a pure function must be pure.
THIS EXAMPLE
The double() and quadruple() functions are both pure. quadruple() calls double() — valid because double() is also pure. The logResult() function is NOT pure (it uses Stdout). The mutation adds a call to logResult() inside quadruple().
See Q43 for pure function basics. See Q790 for reassignment in pure.
Example
defines module qa.puritycontracts.impurecall defines function double() as pure -> input as Integer <- rtn as Integer: input * 2 quadruple() as pure -> input as Integer <- rtn as Integer? rtn: double(double(input)) logResult() -> result as Integer stdout <- Stdout() stdout.println($result) defines program ShowPurity() stdout <- Stdout() result <- quadruple(5) logResult(result) stdout.println($result)
Common mistakes
E08130 — Calling the non-pure function logResult() from a pure function is not allowed. Pure functions can only call other pure functions. See ek9 -h E08130 for details.
Incorrect:
rtn: double(double(input))
logResult(rtn)
Correct:
rtn: double(double(input))
Other ways to ask this
- What triggers E08130 none pure call in pure scope?
- How do I fix impure call in pure context?
- What functions can I call from a pure function?
Coming from another language?
Java: no purity enforcement. Python: no purity concept. Rust: no function-level purity, uses ownership for safety. Kotlin: no purity concept. Haskell: IO monad separates pure from impure. EK9: explicit 'as pure' with transitive enforcement — the entire call chain must be pure.
Keywords: function, E08130, side effect, call, chain, pure, impure