How do dispatchers work with sealed classes in EK9?

← Sealed Types and Traits · Ref: Q302

Dispatchers work identically with sealed classes and sealed traits. When a dispatcher's parameter type is a sealed class (one with 'allow only'), the compiler requires handlers for ALL permitted subclasses.

DISPATCHER ON SEALED CLASS

  ShapeProcessor
    process() as dispatcher
      -> shape as Shape
      <- rtn as String: "Unknown"
    process()
      -> circle as Circle
      <- rtn as String: "Circle"
    process()
      -> square as Square
      <- rtn as String: "Square"

If any permitted type is missing a handler, the compiler reports E05260.

This provides compile-time exhaustive pattern matching, ensuring that when a new subclass is added to the 'allow only' list, all dispatchers are updated.

See Q299 for dispatchers with sealed traits, Q301 for sealed class basics. See Q618 for sealed exhaustive dispatch deep dive.

Example

defines module qa.sealedclasses.dispatcher

  defines class

    Shape allow only Circle, Square as open
      name()
        <- rtn as String: "Shape"

    Circle extends Shape
      override name()
        <- rtn as String: "Circle"

    Square extends Shape
      override name()
        <- rtn as String: "Square"

    ShapeProcessor

      process() as dispatcher
        -> shape as Shape
        <- rtn as String: "Unknown"

      process()
        -> circle as Circle
        <- rtn as String: "Circle"

      process()
        -> square as Square
        <- rtn as String: "Square"

  defines function

    testDispatcher()
      processor <- ShapeProcessor()
      circleResult <- processor.process(Circle())
      squareResult <- processor.process(Square())
      require circleResult?
      require squareResult?

Common mistakes

E05030 — Classes are closed by default in EK9. Without 'as open', Circle and Square cannot extend Shape. The compiler reports E05030 because the type is not open for extension. See ek9 -h E05030 for details.

Incorrect:

Shape allow only Circle, Square

Correct:

Shape allow only Circle, Square as open

E05120 — Overriding a method inherited from Shape requires the 'override' keyword. Without it the compiler reports E05120. See ek9 -h E05120 for details.

Incorrect:

Circle extends Shape
      name()
        <- rtn as String: "Circle"

Correct:

Circle extends Shape
      override name()
        <- rtn as String: "Circle"

E50010 — Triangle is not in 'Shape allow only Circle, Square'. A class not in the sealed class's 'allow only' list cannot extend it. Adding Triangle without updating the list triggers E50010. See ek9 -h E50010 for details.

Incorrect:

Triangle extends Shape
      override name()
        <- rtn as String: "Triangle"

Correct:

Shape allow only Circle, Square as open
Other ways to ask this
  • Can I use dispatchers with sealed classes?
  • Does dispatcher exhaustiveness work for sealed classes?
  • How do I dispatch on a sealed class?

Coming from another language?

Java: exhaustive switch on sealed classes (Java 21+). Kotlin: exhaustive when expressions on sealed classes. Rust: exhaustive match on enums. EK9: dispatcher exhaustiveness on sealed classes provides the same compile-time guarantee.

Keywords: pattern, exhaustive, permit, matching, dispatch, class, closed, only, allow, handler, allow-only, sealed, dispatcher