Why must the negate operator ~ return the same type as its class?

← Operators and Expressions · Ref: Q864

The negate operator ~ must return the SAME type as the enclosing class. Returning a different type is a semantic error (E07410).

WHAT NEGATE DOES

Negate produces the logical or arithmetic inverse of the current object:

  Inverter -> negated Inverter
  Polarity -> opposite Polarity
  Toggle -> flipped Toggle

CORRECT PATTERN

  operator ~ as pure
    <- rtn as Inverter: Inverter()

The return type (Inverter) matches the enclosing class (Inverter).

INCORRECT PATTERN

  operator ~ as pure
    <- rtn as Float: 1.0

Returning Float from an Inverter class triggers E07410 because Float is not Inverter.

USAGE

  original <- Inverter(true)
  negated <- ~original  // negated is an Inverter

See Q238 for operator overview. See Q839 for promote operator (which must return a DIFFERENT type).

Example

defines module qa.operators.negate.same.type

  defines class

    <?-
      Inverter with negate operator returning the same type.
      This is the correct pattern for negation.
    -?>
    Inverter
      active <- true

      Inverter() as pure
        -> initialState as Boolean
        active :=: initialState

      operator ~ as pure
        <- rtn as Inverter: Inverter(active)

      operator $ as pure
        <- rtn as String: `active: ${active}`

      default operator ?

  defines program

    NegateDemo()
      stdout <- Stdout()
      original <- Inverter(true)
      negated <- ~original
      stdout.println($negated)

Common mistakes

E07410 — The negate operator ~ must return the same type as the enclosing class. Returning Float from an Inverter class is not valid negation. Return an Inverter instead. See ek9 -h E07410 for details.

Incorrect:

      operator ~ as pure
        <- rtn as Float: 1.0

Correct:

      operator ~ as pure
        <- rtn as Inverter: Inverter(active)
Other ways to ask this
  • What triggers E07410 MUST_RETURN_SAME_AS_CONSTRUCT_TYPE?
  • Why does my negate operator fail with wrong return type?
  • How do I correctly implement the ~ negate operator in EK9?

Coming from another language?

Java: No negate operator for custom types; bitwise ~ returns int/long. Python: __invert__ can return any type (no enforcement). Rust: Not trait requires Output=Self by convention but not enforced by compiler. Kotlin: operator fun not() can return any type. EK9: operator ~ enforces return type matches enclosing class at compile time.

Keywords: negate, operator, same, E07410, construct, type, ~, return