Dispatch on Shape type to produce a description for Circle, Square, and Triangle.

← Control Flow · Ref: Q1147

Use a dispatcher method on a class with overloads for each type:

  describe() as dispatcher
    -> shape as Shape
    <- rtn as String: "Unknown"
  describe()
    -> shape as Circle
    <- rtn as String: "A circle"

Mark the base method 'as dispatcher'. The compiler generates dispatch logic automatically. No instanceof, no casting, no switch-on-type. This is the ONLY way to do type-based dispatch in EK9. See Q1121 for sealed dispatcher. See Q1122 for dispatcher with fallback.

Example

defines module qa.controlflow.switchontype

  defines trait

    Shape allow only Circle, Square, Triangle
      name() as abstract
        <- rtn as String?

  defines class

    Circle with trait of Shape
      override name()
        <- rtn as String: "Circle"

    Square with trait of Shape
      override name()
        <- rtn as String: "Square"

    Triangle with trait of Shape
      override name()
        <- rtn as String: "Triangle"

    ShapeDescriber

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

      describe()
        -> shape as Circle
        <- rtn as String: "A circle with curved edges"

      describe()
        -> shape as Square
        <- rtn as String: "A square with four equal sides"

      describe()
        -> shape as Triangle
        <- rtn as String: "A triangle with three sides"

  defines program

    SwitchOnTypeDemo()
      stdout <- Stdout()
      describer <- ShapeDescriber()

      shapes <- List() of Shape
      shapes += Circle()
      shapes += Square()
      shapes += Triangle()

      for shape in shapes
        description <- describer.describe(shape)
        stdout.println(description)

Common mistakes

E01010 — EK9 has no instanceof keyword. Use 'as dispatcher' on a method to dispatch on runtime types. The compiler generates the dispatch logic. See ek9 -h E01010 for details.

Incorrect:

if shape instanceof Circle

Correct:

describe() as dispatcher
        -> shape as Shape

E50060 — EK9 has no getClass() method and switch cannot dispatch on types. Use the dispatcher pattern with method overloads for each type. See ek9 -h E50060 for details.

Incorrect:

switch shape.getClass()
        case Circle
          rtn: "A circle"

Correct:

      describe() as dispatcher
        -> shape as Shape
        <- rtn as String: "Unknown shape"
Other ways to ask this
  • Write code to handle different subtypes using EK9's dispatcher pattern
  • I have a sealed Shape hierarchy and need type-specific behavior for each shape
  • Given a Shape that could be Circle, Square, or Triangle, dispatch to the correct handler
  • In Java I'd use instanceof checks. Write the EK9 dispatcher equivalent

Coming from another language?

Java: instanceof + cast chain or visitor pattern. Kotlin: sealed class + when(shape) { is Circle -> }. Rust: enum + match. Python: isinstance() checks. EK9: sealed trait + dispatcher — compiler generates dispatch, no casting, no instanceof.

Keywords: sealed, trait, dispatch, shape, type, dispatcher, instanceof, overload, pattern