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

#!ek9
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: ai, clone, common-error, confuse, equals, hallucination, hashcode, instanceof, isset, migrate, mistake, operator, pitfall, tostring, wrong