Why does AI confuse EK9 operators with other languages?

← What AI Gets Wrong About EK9 · Ref: Q279

AI models map Java and Python method names to EK9 when operators should be used. EK9 has a fixed set of operators with specific symbols. AI frequently generates method calls that do not exist.

COMMON AI MISTAKES AND CORRECT EK9

  .toString() does not exist. Use $ (the string operator). Always returns String.
  .toJson() does not exist. Use $$ (the JSON operator). Always returns JSON.
  .hashCode() does not exist. Use #? (the hashcode operator). Returns Integer.
  .equals(other) does not exist. Use == (equality operator). Returns Boolean.
  .clone() does not exist. Use :=: (copy operator) or copy constructor MyType(original).
  .isPresent() does not exist. Use ? (isSet operator). Returns Boolean.
  !x for logical NOT is wrong for Boolean. Use ~x (tilde, for Boolean, Bits and Byte).
  x instanceof T does not exist. Use traits and dispatching instead.

OPERATOR DEFINITIONS IN A CLASS

When defining operators on your own types, use the 'operator' keyword:

  operator $ as pure
    <- rtn as String: ...
  operator #? as pure
    <- rtn as Integer: ...
  operator == as pure
    -> other as MyType
    <- rtn as Boolean: ...
  operator <=> as pure
    -> other as MyType
    <- rtn as Integer: ...

A type declares its SAMENESS once: '<=>' for an ordered type or '==' for an equatable-only type, never both. The rest ('<>' from '==', and '==' '<>' '<' '<=' '>' '>=' from '<=>') is generated; writing them for the type itself is E07181. A hand-written sameness needs a hand-written '#?' hashing what it compares, and a '#?' needs a sameness to agree with (E07184).

NOT-EQUAL

Both != and <> are valid for not-equal in EK9. AI often uses only != which works, but <> is also correct and preferred in some contexts.

COPY PATTERNS

Two ways to copy: the :=: operator mutates the target, the copy constructor creates a new instance:

  target :=: source
  copied <- MyType(original)

See Q238 for the complete operator set. See Q239 for comparison operators. See Q240 for arithmetic operators. See Q241 for mutation operators. See Q281 for verifying AI code.

Example

defines module qa.ai.mistakes.operators

  defines class

    // === Class to test $ operator confusion ===

    Labelled
      label as String: String()

      Labelled()
        -> initialLabel as String
        label: initialLabel

      operator $ as pure
        <- rtn as String: String(label)

      override operator ? as pure
        <- rtn as Boolean: label?

    // === Class to test #? operator confusion ===

    Coded
      code as Integer: Integer()

      Coded()
        -> initialCode as Integer
        code: initialCode

      operator #? as pure
        <- rtn as Integer: Integer(code)

      operator == as pure
        -> other as Coded
        <- rtn as Boolean: code == other.code

      override operator ? as pure
        <- rtn as Boolean: code?

    // === Class to test == operator confusion ===

    Ranked
      rank as Integer: Integer()

      Ranked()
        -> initialRank as Integer
        rank: initialRank

      operator == as pure
        -> other as Ranked
        <- rtn as Boolean: rank == other.rank

      operator #? as pure
        <- rtn as Integer: #? rank

      override operator ? as pure
        <- rtn as Boolean: rank?

  defines program

    OperatorConfusionDemo()
      stdout <- Stdout()

      // === $ REPLACES toString() ===

      item <- Labelled("hello")
      stdout.println(`Item: ${item}`)

      // === #? REPLACES hashCode() ===

      coded <- Coded(42)
      hash <- #?coded
      stdout.println(`Hash: ${hash}`)

      // === == REPLACES equals() ===

      rankA <- Ranked(1)
      rankB <- Ranked(1)
      stdout.println(`Equal: ${rankA == rankB}`)

      // === ~ FOR BOOLEAN NOT ===

      active <- true
      inactive <- ~active
      stdout.println(`Active: ${active}, Inactive: ${inactive}`)

Common mistakes

E04020 — EK9 has no toString() method. Use the $ operator for string conversion. Without it, the type cannot be used in string interpolation. See ek9 -h E04020 for details.

Incorrect:

toString() as pure

Correct:

operator $ as pure

E07620 — EK9 has no hashCode() method. Use the #? operator for hash code computation (and, because a type's equality and hash go together, declare '==' beside it). Without the operator, the #? prefix operator is not available on the type. See ek9 -h E07620 for details.

Incorrect:

hashCode() as pure
        <- rtn as Integer: Integer(code)

Correct:

operator #? as pure
        <- rtn as Integer: Integer(code)

      operator == as pure
        -> other as Coded
        <- rtn as Boolean: code == other.code

E07620 — EK9 has no equals() method. Use the == operator for equality comparison (and, because a type's equality and hash go together, declare '#?' beside it). Without the operator, the == infix operator is not available on the type. See ek9 -h E07620 for details.

Incorrect:

equals() as pure
        -> other as Ranked
        <- rtn as Boolean: rank == other.rank

Correct:

operator == as pure
        -> other as Ranked
        <- rtn as Boolean: rank == other.rank

      operator #? as pure
        <- rtn as Integer: #? rank

E50060 — EK9 has no toString() method, so the call cannot be resolved: E50060. Use the $ operator, which string interpolation applies for you. See ek9 -h E50060 for details.

Incorrect:

stdout.println(`Item: ${item.toString()}`)

Correct:

stdout.println(`Item: ${item}`)

E50060 — EK9 has no hashCode() method, so the call cannot be resolved: E50060. Use the #? prefix operator. See ek9 -h E50060 for details.

Incorrect:

hash <- coded.hashCode()

Correct:

hash <- #?coded
Other ways to ask this
  • Why does AI generate toString() instead of the $ operator?
  • What are the correct EK9 operator equivalents?
  • How do I fix AI-generated method calls that should be operators?

Coming from another language?

Java: toString(), hashCode(), equals(), clone(), instanceof, !boolean. Python: str(), hash(), __eq__, copy.copy(), isinstance(), not. Rust: Display trait, Hash trait, PartialEq, Clone, matches!, !bool. Go: Stringer interface, no operator overloading. Kotlin: toString(), hashCode(), equals(), !boolean. EK9: $ for string, $$ for JSON, #? for hashcode, == for equality, :=: for copy, ? for isSet, ~ for NOT (Boolean/Bits/Byte), traits and dispatching replace instanceof.

Keywords: confuse, pitfall, equals, operator, hallucination, instanceof, hashcode, common-error, isset, wrong, tostring, clone, migrate, mistake, ai