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