How do the coalescing operators <?, >?, <=?, >=? work on a custom class?

← Operators and Expressions · Ref: Q1050

The coalescing operators return one of the two operands based on comparison:

  <? returns the lesser value (minimum)
  >? returns the greater value (maximum)
  <=? returns the left if left <= right, else right
  >=? returns the left if left >= right, else right

To use these on a custom class, the class must implement the corresponding comparison operators (<, >, <=, >=).

  score1 <- Score(85)
  score2 <- Score(92)
  minimum <- score1 <? score2     returns Score(85)
  maximum <- score1 >? score2     returns Score(92)

They also handle unset values safely — if either operand is unset, the result reflects that.

These replace patterns like:

  if a < b then result := a else result := b

With just:

  result <- a <? b

See Q963 for <? in detail. See Q964 for >? in detail. See Q1049 for comparison operators on records. See Q243 for coalescing with unset values.

Example

defines module qa.operators.coalescingclass

  defines class

    Score
      points as Integer: 0

      Score() as pure
        -> points as Integer
        this.points :=: points

      operator <=> as pure
        -> other as Score
        <- rtn as Integer: points <=> other.points

      operator < as pure
        -> other as Score
        <- rtn as Boolean: (this <=> other) < 0

      operator > as pure
        -> other as Score
        <- rtn as Boolean: (this <=> other) > 0

      operator <= as pure
        -> other as Score
        <- rtn as Boolean: (this <=> other) <= 0

      operator >= as pure
        -> other as Score
        <- rtn as Boolean: (this <=> other) >= 0

      operator == as pure
        -> other as Score
        <- rtn as Boolean: points == other.points

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

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

      operator $ as pure
        <- rtn as String: `Score(${points})`

  defines program

    CoalescingClassDemo()
      stdout <- Stdout()

      alice <- Score(85)
      bob <- Score(92)
      charlie <- Score(78)

      //Coalescing: find minimum and maximum
      minimum <- alice <? bob
      maximum <- alice >? bob
      stdout.println(`Min: ${minimum}`)
      stdout.println(`Max: ${maximum}`)

      //Chain coalescing for three values
      lowest <- alice <? bob <? charlie
      highest <- alice >? bob >? charlie
      stdout.println(`Lowest: ${lowest}`)
      stdout.println(`Highest: ${highest}`)

Common mistakes

E50001 — EK9 has no Math class; use the '<?' coalescing operator to get the lesser of two values. See ek9 -h E50001 for details.

Incorrect:

minimum <- Math.min(alice, bob)

Correct:

minimum <- alice <? bob
Other ways to ask this
  • What are the comparison coalescing operators in EK9?
  • Show me <? and >? on a class with examples
  • How do I find the minimum or maximum of two objects?

Coming from another language?

Java: Math.min(a,b) / Math.max(a,b). Python: min(a,b) / max(a,b). Rust: a.min(b) / a.max(b). EK9: a <? b / a >? b as operators.

Keywords: compare, operator, class, maximum, coalescing, minimum