What happens if a dispatcher handler's parameter type is outside the hierarchy?
← Dispatcher Validation · Ref: Q614
Every dispatcher handler's parameter type must be a subtype of the dispatcher entry's parameter type. If a handler specifies a type that is not in the hierarchy, the compiler raises E05210.
WHY TYPE HIERARCHY MATTERS
Dispatchers route calls based on runtime type. The entry method declares a base type (e.g., Animal). Each handler declares a specific subtype (e.g., Dog, Cat). At runtime, the dispatcher checks the actual type and routes to the matching handler. If a handler type is not in the hierarchy, it can never match.
EXAMPLE OF THE ERROR
If the dispatcher entry takes Animal and a handler takes Vehicle, no Animal can ever be a Vehicle. The handler is unreachable and indicates a design error.
CORRECT PATTERN
All handlers must use subtypes of the entry's parameter type:
handle() as dispatcher -> a as Animal handle() -> a as Dog //OK: Dog extends Animal handle() -> a as Cat //OK: Cat extends Animal
SEPARATE DISPATCHERS FOR SEPARATE HIERARCHIES
If you need to dispatch on multiple unrelated type hierarchies, create separate dispatchers. Each dispatcher handles one hierarchy.
See Q60 for dispatcher fundamentals. See Q615 for return type matching. See Q619 for two-parameter dispatchers.
Example
defines module qa.dispatchervalidation.hierarchy defines class Animal as abstract speak() as pure abstract <- rtn as String? default operator ? Dog extends Animal override speak() as pure <- rtn as String: "woof" default operator ? Cat extends Animal override speak() as pure <- rtn as String: "meow" default operator ? Bird extends Animal override speak() as pure <- rtn as String: "tweet" default operator ? //CORRECT: all handler types are in the Animal hierarchy AnimalHandler handle() as dispatcher -> animal as Animal <- rtn as String: "Animal: " + animal.speak() handle() -> animal as Dog <- rtn as String: "Dog says: " + animal.speak() handle() -> animal as Cat <- rtn as String: "Cat says: " + animal.speak() handle() -> animal as Bird <- rtn as String: "Bird says: " + animal.speak() defines function testHierarchyDispatch() handler <- AnimalHandler() dog <- Dog() cat <- Cat() bird <- Bird() require handler.handle(dog) == "Dog says: woof" require handler.handle(cat) == "Cat says: meow" require handler.handle(bird) == "Bird says: tweet"
Common mistakes
E50010 — The dispatcher entry takes Animal. A handler parameter type must be a subtype of Animal. Vehicle is completely unrelated and would never match at runtime. See ek9 -h E50010 for details.
Incorrect:
handle() -> vehicle as Vehicle
Correct:
handle() -> animal as Dog
E05220 — The dispatcher entry returns String. All handlers must return the same type. A handler returning Integer would create an inconsistent return type. See ek9 -h E05220 for details.
Incorrect:
handle() -> animal as Cat <- rtn as Integer: 0
Correct:
handle() -> animal as Cat <- rtn as String: "Cat says: " + animal.speak()
Other ways to ask this
- What is E05210 in EK9?
- Why must dispatcher handler types be in the same hierarchy?
- Can a dispatcher handle unrelated types?
Coming from another language?
Java: method overloading doesn't check hierarchy, resolved at compile time. Kotlin: no runtime dispatcher, uses when + is checks. Rust: match on enum variants (closed hierarchy). Go: type switch operates on interfaces. EK9: E05210 enforces that all dispatcher handler parameter types are within the dispatch hierarchy.
Keywords: handler, extends, unrelated, subtype, dispatch, E05210, type, parameter, validate, dispatcher, hierarchy, ambiguity