E07183: sameness ('<=>' or '==') must have a body where it is declared; it cannot be abstract

Category: E07xxx Full resolution · Reported in phase: FULL_RESOLUTION · Classification: SAMENESS_MUST_BE_CONCRETE · All error codes

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: