E05150: 'pure' in super requires 'pure' for this definition
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:
- Add 'as pure' to your override method
- Remove any side effects from the method body
- 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
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:
- Q54: What are pure functions and what is the difference between Consumer and Acceptor?
- Q561: Why must an override of a pure method also be pure?
- Q562: Why can't I add 'as pure' to an override when the parent method isn't pure?
- Q567: How does purity flow through multi-level inheritance chains?
- Q569: How do traits interact with pure method contracts?
- Q578: What is the relationship between open, abstract, and override?
- Q588: How do functions extend other functions in EK9?
- Q595: How does purity interact with abstract function extension?
- Q601: How do dynamic functions replace nested functions in EK9?
- Q677: How does abstract implementation flow through a three-level hierarchy?
- Q699: What are the return type and parameter type rules for method overrides?
- Q707: How do I use Consumer and Acceptor with concrete types?
- Q708: How do I use Supplier and Producer to create values?
- Q709: How do I use Predicate and Assessor for testing conditions?
- Q710: How do I use Function and Routine for transformations?
- Q711: How do I use BiConsumer and BiAcceptor with two parameters?
- Q712: How do I use BiPredicate and BiAssessor to test two values?
- Q713: How do I use BiFunction and BiRoutine for two-input transformations?
- Q714: How do I use the Comparator function type for ordering?
- Q715: How do I use UnaryOperator for same-type transformations?