E07183: sameness ('<=>' or '==') must have a body where it is declared; it cannot be abstract
What went wrong
(The 'concrete' of this error's old name means only 'has a body'; it has nothing to do with the kind of type.) A '<=>' or '==' comparing the type with itself is abstract (or a bodiless trait operator). Sameness must have a body where it is declared: if each implementer supplied its own, two sibling types would compare each other by different rules and a mixed collection could not be ordered consistently.
EK9 codifies Java's equals/hashCode/compareTo contract (Effective Java items 10, 11 and 14) as a compile error: a type defines its SAMENESS once - '<=>' if it is ordered, '==' if it is equatable only - and every other comparison is generated from it, so two ways of saying "equal" cannot disagree.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 1402 (How do I define equality and ordering for my own type?)
How to fix it
Write the body on the abstraction over its own abstract accessors, and let the implementers supply the data. In the [EXAMPLE] section below the trait 'Ranked' declares an abstract 'rank()' and writes its '<=>' (and its '#?') over it; the trait then gets '<(Ranked)' and the rest generated.
Common causes
- A trait declaring 'operator <=>' with no body for implementers to override
See also
- E07182: sameness declared again below an abstract base or trait
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E07183: sameness ('<=>' or '==') must have a body where it is declared; it cannot be abstract
#!ek9 defines module error.e07183.bad defines trait Ranked rank() as pure <- rtn as Integer? //Sameness must say how two values compare where it is declared operator <=> as pure -> other as Ranked <- rtn as Integer?
Fixed: Give it a body, over abstract accessors
#!ek9 defines module error.e07183.good defines trait Ranked rank() as pure <- rtn as Integer? //Concrete, written over the trait's own abstract accessor operator <=> as pure -> other as Ranked <- rtn as Integer: rank() <=> other.rank() operator #? as pure <- rtn as Integer: #?rank()
Questions and answers
These Q&A entries show E07183 and its fix: