What do the $ and #? operators mean in EK9?
← Operators and Expressions · Ref: Q897
EK9 has dedicated operator symbols for string conversion and hashcode. These are NOT what you might expect from other languages.
$ OPERATOR — STRING CONVERSION (NOT interpolation)
The $ operator calls the _string() method to convert any value to its String representation:
age <- 25 ageText <- $age converts Integer 25 to String "25" point <- Point(3.0, 4.0) pointText <- $point calls point._string()
IMPORTANT: $ is NOT string interpolation. For interpolation, EK9 uses backtick strings with ${...}:
greeting <- `Hello ${name}` interpolation inside backtick string nameStr <- $name standalone string conversion
Inside backtick strings, ${$variable} uses $ to convert to string:
stdout.println(`Age is ${$age}`) ${...} is the interpolation, $ inside converts
#? OPERATOR — HASHCODE (lowercase 'c')
The #? operator calls _hashcode() and returns an Integer hash value:
hashValue <- #? myObject calls myObject._hashcode()
Note: it is _hashcode (lowercase c), not _hashCode (Java style).
#^ OPERATOR — PROMOTE (type conversion)
The #^ operator calls _promote() to convert to a wider type:
anInteger <- 42 asFloat <- #^ anInteger promotes Integer to Float
IMPORTANT: #^ is NOT Python list comprehension. It is type PROMOTION only.
OPERATOR METHOD NAMES
- $ calls _string()
- #? calls _hashcode()
- #^ calls _promote()
- ? calls _isSet()
- <=> calls _cmp()
- == calls _eq()
- <> calls _neq()
See Q96 for all operators. See Q238 for operator enforcement. See Q245 for implementing operators.
Example
defines module qa.operators.stringhash defines record Coordinate xPos as Float: 0.0 yPos as Float: 0.0 Coordinate() -> initialX as Float initialY as Float this.xPos :=: initialX this.yPos :=: initialY default operator defines function showConversions() as pure -> label as String coordinate as Coordinate <- rtn as String: String() // $ operator converts to String via _string() coordText <- $coordinate hashVal <- #? coordinate rtn := `${label}: text=${coordText}, hash=${hashVal}` defines program StringAndHashDemo() stdout <- Stdout() // $ operator — string CONVERSION (not interpolation) age <- 25 ageText <- $age stdout.println(`Age as string: ${ageText}`) // Inside backtick strings: ${variable} for conversion price <- 19.99 stdout.println(`Price: ${price}`) // #? operator — hashcode greeting <- "Hello" greetingHash <- #? greeting stdout.println(`Hash of greeting: ${greetingHash}`) // #^ operator — promote (type conversion) wholeNumber <- 42 promoted <- #^ wholeNumber stdout.println(`Promoted: ${promoted}`) // Custom type with operators origin <- Coordinate() target <- Coordinate(3.0, 4.0) stdout.println(showConversions("Origin", origin)) stdout.println(showConversions("Target", target))
Common mistakes
E07620 — Use $ to convert an Integer to String before concatenation — "Age: " + age has no defined + operator for a String and an Integer. See ek9 -h E07620 for details.
Incorrect:
ageText <- "Age: " + age
Correct:
ageText <- $age
Other ways to ask this
- What is the $ operator in EK9?
- What is the #? operator in EK9?
- How does string conversion work in EK9?
- How does hashcode work in EK9?
Coming from another language?
Java: toString() and hashCode() are method calls. Python: str() and hash() are built-in functions, $ has no meaning. Rust: Display trait for string, Hash trait for hashing. Go: String() method convention. Kotlin: toString() and hashCode() like Java. EK9: $ for _string() conversion, #? for _hashcode(), #^ for _promote() — these are operator symbols, not method calls.
Keywords: conversion, operator, backtick, interpolation, string, promote, dollar, hashcode