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 promotes an Integer to a Float automatically (the #^ operator is applied for you, at assignment and at call arguments), but every other conversion must be explicit.

COMMON FIXES

Integer to Float: #^ promote, or let the declared type promote it:

  intVal <- 42
  floatVal <- #^ intVal
  widened 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: a String where a Float is expected is rejected, while an Integer is promoted for you:

  processFloat() as pure
    -> floatInput as Float
    <- rtn as String: `Processed: ${floatInput}`
  rejected <- processFloat("42")   // ERROR E06270

These are fine, the Integer 42 is promoted to Float:

  processFloat() as pure
    -> floatInput as Float
    <- rtn as String: `Processed: ${floatInput}`
  fromInteger <- processFloat(42)
  fromLiteral <- processFloat(42.0)
  explicit <- processFloat(#^ 42)

Operator Return Types (enforced):

  - == must return Boolean (E07520)
  - $ must return String (E07570)
  - #? and <=> must return Integer (E07550)
  - a mutating operator such as += must NOT return a value (E07430)

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 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(`Parsed: ${bad}`)
      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: Integer promotes to Float automatically, other conversions explicit (#^ promotion, $ to string, constructor conversion, dispatcher for type-specific logic).

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