How do I use the #^ promote operator on a class?

← Operators and Expressions · Ref: Q1048

Define operator #^ on your class to convert it to a wider or simpler type. The return type MUST be different from the class.

  defines class
    Percentage
      amount as Float: 0.0
      operator #^ as pure
        <- rtn as Float: amount

Usage:

  discount <- Percentage(15.0)
  asFloat <- #^ discount

The compiler uses #^ automatically when a Percentage is used where a Float is expected. This is type-safe widening — the compiler knows exactly how to convert.

Common patterns:
- Percentage to Float (domain type to primitive)
- Measurement to Float (unit type to raw number)
- UserId to Integer (wrapper to underlying value)

The #^ operator must be pure, take no parameters, and return a different type. The compiler enforces this with E07420.

See Q912 for what #^ means. See Q1052 for #^ on a record. See Q839 for promote return type rules.

Example

defines module qa.operators.promoteclass

  defines class

    Percentage
      amount as Float: 0.0

      Percentage() as pure
        -> amount as Float
        this.amount :=: amount

      operator #^ as pure
        <- rtn as Float: amount

      override operator ? as pure
        <- rtn as Boolean: amount?

      operator $ as pure
        <- rtn as String: `${amount}%`

  defines function

    applyDiscount() as pure
      ->
        price as Float
        rate as Float
      <- rtn as Float: price - (price * rate)

  defines program

    PromoteClassDemo()
      stdout <- Stdout()

      discount <- Percentage(15.0)
      stdout.println(`Discount: ${discount}`)

      //Promote to Float for arithmetic
      rawRate <- #^ discount
      price <- 100.0
      finalPrice <- applyDiscount(price, rawRate)
      stdout.println(`Final: ${finalPrice}`)

Common mistakes

E07420 — The #^ promote operator must return a DIFFERENT type. Returning the same type defeats the purpose and triggers E07420.

Incorrect:

      operator #^ as pure
        <- rtn as Percentage: Percentage(amount)

Correct:

      operator #^ as pure
        <- rtn as Float: amount
Other ways to ask this
  • How does #^ type promotion work on a class?
  • Show me the promote operator on a custom class
  • How do I widen a class type to a simpler type?

Coming from another language?

Java: implicit primitive widening (int to double). Rust: explicit 'as' casting. EK9: #^ operator provides explicit, type-safe promotion.

Keywords: class, widening, promote, conversion, operator