Why can't I declare 'operator !=' on my EK9 type?
← Operators and Expressions · Ref: Q1320
EK9's not-equal operator is '<>' (mathematical notation), not the C-family '!='. When you declare an operator on a type you must name it '<>'. Declaring 'operator != as pure' triggers E07640 (BAD_NOT_EQUAL_OPERATOR) because '!=' is not a valid EK9 operator symbol for a declaration.
Replace 'operator !=' with 'operator <>'. The operator must be pure, take exactly one argument, and return Boolean.
For comparison with the type ITSELF you write neither: the type declares its sameness once - '<=>' for an ordered type, or '==' for an equatable-only type - with a matching '#?', and the compiler generates '<>' (and ==, <, <=, >, >= from '<=>'). Hand-writing a self '<>' is E07181. You declare 'operator <>' by hand only against an unrelated type, as Score does with Integer here. EK9 chose '<>' because it is the mathematical not-equal form (the same as Pascal, SQL and BASIC) and composes naturally with '<' and '>'.
See Q238 for the complete fixed operator set. See Q239 for comparison and ordering operators.
Example
defines module qa.operators.notequal defines class Score points <- Integer() Score() as pure -> points as Integer this.points :=: points //The sameness: ==, <>, <, <=, >, >= with another Score are generated from it, //so '<>' for Score is never written by hand operator <=> as pure -> other as Score <- rtn as Integer: points <=> other.points operator #? as pure <- rtn as Integer: #?points //THE FIX: EK9's not-equal operator is '<>', NOT '!='. //Declaring 'operator !=' would trigger E07640. //(Here '<>' compares with an unrelated type, Integer, so it is written by hand.) operator <> as pure -> threshold as Integer <- rtn as Boolean: points <> threshold operator $ as pure <- rtn as String: $points override operator ? as pure <- rtn as Boolean: points? defines program NotEqualOperatorDemo() stdout <- Stdout() a <- Score(10) b <- Score(20) stdout.println(`Equal: ${a == b}`) stdout.println(`Not equal: ${a <> b}`)
Common mistakes
E07640 — EK9 uses the mathematical not-equal symbol '<>', not the C-family '!='. Declaring 'operator !=' is not a valid EK9 operator name and triggers E07640. Rename the declaration to 'operator <>' (pure, one argument, returns Boolean). For comparison with the type itself, write neither: declare the sameness ('<=>' or '==') and '<>' is generated. See ek9 -h E07640 for details.
Incorrect:
operator != as pure -> threshold as Integer <- rtn as Boolean: points <> threshold
Correct:
operator <> as pure -> threshold as Integer <- rtn as Boolean: points <> threshold
E07181 — '<>' with the type itself is generated from its sameness (here '<=>'), so declaring it by hand for Score is E07181 (COMPARISON_GENERATED_FROM_SAMENESS). Delete it - 'a <> b' already works. See ek9 -h E07181 for details.
Incorrect:
operator #? as pure <- rtn as Integer: #?points operator <> as pure -> other as Score <- rtn as Boolean: points <> other.points
Correct:
operator #? as pure <- rtn as Integer: #?points
Other ways to ask this
- What triggers E07640 BAD_NOT_EQUAL_OPERATOR?
- How do I implement not-equal on a custom EK9 class?
- Why does EK9 reject '!=' as an operator name?
Coming from another language?
Java/C++/Python/Rust/JavaScript: not-equal is '!=' and (where overloading exists) you implement it under that symbol or as a negated equals. EK9: the only not-equal operator symbol is '<>', and the compiler rejects a '!=' declaration at compile time (E07640, phase EXPLICIT_TYPE_SYMBOL_DEFINITION) rather than silently accepting an alternate spelling.
Keywords: comparison, <>, !=, operator, sameness, E07181, inequality, E07640, neq, not, equal, declaration