Why is the compiler reporting a type mismatch?

← Debugging and Troubleshooting · Ref: Q250

Type mismatch errors occur when a value of one type is used where another is expected. EK9 has no implicit coercion; all conversions must be explicit.

COMMON FIXES

Integer to Float: #^ promote or assignment:

  floatVal <- #^ intVal
  floatVal as Float: intVal

Any to String: $ operator or interpolation:

  text <- $count
  message <- `Count is ${count}`

String to Integer/Float: constructors (unset if invalid):

  parsed <- Integer("42")

Parameter Mismatch: types must match exactly:

  WRONG:  processFloat(42)
  RIGHT:  processFloat(#^ 42) or processFloat(42.0)

Operator Return Types (enforced):

  == returns Boolean (E07550), $ returns String (E07580), #? returns Integer (E07570), <=> returns Integer (E07520). Mutation operators must NOT return (E07410).

DISPATCHER PATTERN

For type-specific processing, use dispatcher instead of casting. Runtime routes to the most specific overload.

See Q24 for type conversion and dispatcher. See Q25 for promote operator. See Q238 for operator rules. See Q242 for conversion operators.

Example

defines module qa.debugging.typemismatch

  defines function

    processFloat() as pure
      -> floatInput as Float
      <- rtn as String: `Processed: ${floatInput}`

  defines class

    Measurement
      reading <- Float()
      label <- String()

      Measurement()
        ->
          initialReading as Float
          measureLabel as String
        this.reading :=: initialReading
        this.label :=: measureLabel

      operator $ as pure
        <- rtn as String: `${label}: ${reading}`

      operator == as pure
        -> other as Measurement
        <- rtn as Boolean: reading == other.reading

      operator <=> as pure
        -> other as Measurement
        <- rtn as Integer: reading <=> other.reading

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

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

  defines program

    TypeMismatchDemo()
      stdout <- Stdout()

      // Integer to Float promotion with #^
      intVal <- 42
      floatVal <- #^ intVal
      stdout.println(`Promoted: ${floatVal}`)

      // Direct Float assignment (compiler inserts promotion)
      widened as Float: intVal
      stdout.println(`Widened: ${widened}`)

      // Using promoted value in function call
      result <- processFloat(#^ intVal)
      stdout.println(result)

      // String conversion with $ operator
      count <- 100
      countText <- $count
      stdout.println(`As string: ${countText}`)

      // Constructor conversion
      parsed <- Integer("99")
      if parsed?
        stdout.println(`Parsed: ${parsed}`)

      // Invalid parse produces unset
      bad <- Integer("abc")
      if bad?
        stdout.println("Should not print")
      else
        stdout.println("Invalid parse detected")

      // Correct operator usage
      m1 <- Measurement(10.0, "Width")
      m2 <- Measurement(20.0, "Height")
      stdout.println(`${m1}`)
      stdout.println(`Equal: ${m1 == m2}`)
      stdout.println(`Compare: ${m1 <=> m2}`)

Common mistakes

E06270 — A String cannot be passed where Float is expected. There is no automatic promotion from String to Float. Use a Float literal or the #^ operator to promote Integer to Float. See ek9 -h E06270 for details.

Incorrect:

result <- processFloat("42")

Correct:

result <- processFloat(#^ intVal)
Other ways to ask this
  • How do I fix type mismatch errors in EK9?
  • What causes type errors in EK9?
  • How do I convert between types correctly in EK9?

Coming from another language?

Java: implicit widening, ClassCastException. Python: dynamic typing, TypeError. Rust/Go: no implicit conversions. EK9: explicit #^ promotion, $ to string, constructor conversion, dispatcher for type-specific logic.

Keywords: implicit, return, operator, cast, fix, compile, error-message, mismatch, type, promote, troubleshoot, parameter, error, explicit, debug, conversion, coerce