E05290: parents disagree on 'pure' - one method cannot honour both a pure and a non-pure contract
What went wrong
A method stands in for several parent declarations - a super class and a trait, or two traits - and those parents DISAGREE on 'pure': at least one declares the method 'pure' and at least one does not. 'pure' is always part of the contract, so an override must match every parent that declares the method. When the parents disagree, no single method can honour both contracts.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 1401 (What happens when a method comes from both a pure parent...)
Rationale
A caller holding the pure parent relies on the method having no side effects. A caller holding the non-pure parent relies on it being free to have them. One body cannot be both, so combining these parents on one type is rejected - whichever parent is listed first. In the [EXAMPLE] section below, a Circle extends a Base whose 'describe()' is not pure and has the trait Strict whose 'describe()' is pure: Circle's override, pure or not, breaks one of them. The fix makes both parents declare it 'pure'.
How to fix it
- Make the parents agree: mark both declarations 'pure', or neither
- Or stop combining them - implement the pure trait on a different type
Common causes
- Adding a pure trait to a class whose super already declares the same method without 'pure'
- Two traits written independently that declare the same method differently
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E05290: parents disagree on 'pure' - one method cannot honour both a pure and a non-pure contract
#!ek9 defines module error.e05290.bad defines trait Strict describe() as pure abstract <- rtn as String? defines class Base as open describe() <- rtn as String: "base" default operator ? Circle extends Base with trait of Strict override describe() <- rtn as String: "circle" default operator ?
Fixed: Make the parents agree: here both declare describe() pure, so the override is pure
#!ek9 defines module error.e05290.good defines trait Strict describe() as pure abstract <- rtn as String? defines class Base as open describe() as pure <- rtn as String: "base" default operator ? Circle extends Base with trait of Strict override describe() as pure <- rtn as String: "circle" default operator ?
Questions and answers
These Q&A entries show E05290 and its fix: