E05190: if any constructor is marked pure, all constructors must be pure
What went wrong
Constructors in a class must have consistent purity - either ALL constructors are pure, or NONE are pure. Mixing pure and non-pure constructors is not allowed.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 564 (Why must all constructors be pure if any one is pure?)
- ek9 -q 565 (How do I write multiple pure constructors with delegation?)
- ek9 -q 586 (How does constructor delegation work with pure constructors?)
- ek9 -q 564 (Why must all constructors be pure if any one is pure?)
- ek9 -q 678 (How do pure and non-pure methods coexist in an override h...)
How to fix it
- Decide if class construction should be pure or not
- Make ALL constructors consistently pure or non-pure
- Remove side effects from pure constructors
Rationale
Object creation should be predictably pure or not:
- Callers can't always choose which constructor is called
- Factory methods might delegate to any constructor
- Consistent purity simplifies reasoning about code
Common causes
- Adding new constructor without matching existing purity
- Wanting one "simple" pure constructor and one "logging" constructor
- Forgetting to mark overloaded constructor as pure
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E05190: if any constructor is marked pure, all constructors must be pure
#!ek9 defines module error.e05190.bad defines class Person name as String: String() nickname as String: String() default Person() Person() -> name as String this.name :=? name //One pure constructor makes the others inconsistent Person() as pure -> name as String nickname as String this.name :=? name this.nickname :=? nickname default operator ?
Fixed: Make every constructor pure (a pure constructor sets properties with :=?)
#!ek9 defines module error.e05190.good defines class Person name as String: String() nickname as String: String() default Person() as pure Person() as pure -> name as String this.name :=? name Person() as pure -> name as String nickname as String this.name :=? name this.nickname :=? nickname default operator ?
Fixed: Or make none of them pure
#!ek9 defines module error.e05190.good.none defines class Person name as String: String() nickname as String: String() default Person() Person() -> name as String this.name: name Person() -> name as String nickname as String this.name: name this.nickname: nickname default operator ?
Questions and answers
These Q&A entries show E05190 and its fix: