E05150: 'pure' in super requires 'pure' for this definition

Category: E05xxx Explicit type symbol definition · Reported in phase: FULL_RESOLUTION · Classification: SUPER_IS_PURE · All error codes

What went wrong

The parent method/function is marked 'pure' (no side effects), but your override is not marked pure. Pure methods can ONLY be overridden by pure methods to preserve the no-side-effects contract.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 561 (Why must an override of a pure method also be pure?)
  • ek9 -q 54 (What are pure functions and what is the difference betwee...)
  • ek9 -q 567 (How does purity flow through multi-level inheritance chains?)
  • ek9 -q 569 (How do traits interact with pure method contracts?)
  • ek9 -q 562 (Why can't I add 'as pure' to an override when the parent ...)

How to fix it

Make the override pure, so it honours the contract the parent already promises.

With tooling, ek9_query_purity_impact (the file and the error line) previews the change read-only: the contract group this override belongs to, and the callees that must themselves become pure before the body can qualify. ek9_fix_purity_contract with mode 'add-pure-to-override' then applies it - use dryRun:true first. Further-derived overrides are cascaded automatically; callers or callees needing their own change come back as a 'purity-cascade' advisory to chain per site. Both tools compute from the same call-graph closure, so the preview and the fix agree.

By hand:

  1. Add 'as pure' to your override method
  2. Remove any side effects from the method body
  3. Ensure method only computes and returns values

Rationale

Callers of parent.calculate() expect no side effects. When they receive a Child instance (polymorphism), child.calculate() MUST uphold that contract. Breaking purity would violate behavioral substitution.

Pure method rules

  • Cannot mutate anything it was given or does not own: no mutating operator (+=, :=:, ...) on a parameter, property or captured value
  • Cannot call non-pure methods or functions
  • May print: Stdout and Stderr declare println() 'as pure' (pragmatic I/O purity), so output is not a reason to drop 'as pure'

Common causes

  • Forgetting to add 'as pure' when overriding pure method
  • Adding logging/debugging that introduces side effects
  • Not realizing parent method was pure

See also

  • E05150: override missing purity (this error)
  • E05160: override adds purity parent doesn't have (opposite)
  • E05290: parents disagree on purity (a super and a trait, or two traits)

Examples

Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.

Fails with E05150: 'pure' in super requires 'pure' for this definition

#!ek9
defines module error.e05150.bad

  defines function

    Measure() as pure abstract
      -> text as String
      <- size as Integer?

    WordLength() is Measure
      -> text as String
      <- size as Integer: length text

Fixed: Keep the purity the super promises

#!ek9
defines module error.e05150.good

  defines function

    Measure() as pure abstract
      -> text as String
      <- size as Integer?

    WordLength() is Measure as pure
      -> text as String
      <- size as Integer: length text

Questions and answers

These Q&A entries show E05150 and its fix: