E05170: dispatcher handler must match the purity of the dispatcher entry point ('pure' on both or on neither)

Category: E05xxx Explicit type symbol definition · Reported in phase: FULL_RESOLUTION · Classification: DISPATCHER_PURE_MISMATCH · All error codes

What went wrong

A dispatcher handler does not match the purity of the dispatcher entry point. The rule runs BOTH ways: a pure entry point ('as pure dispatcher') needs every handler to be 'as pure', and an entry point that is NOT pure needs every handler to be not pure. The message says which way it failed.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 612 (What happens when a dispatcher entry and handler have dif...)
  • ek9 -q 621 (What is the complete set of dispatcher compile-time checks?)

How to fix it

  1. Decide whether the dispatcher as a whole is pure - the entry point is the only signature a caller sees, so it carries that decision
  2. If it is pure: mark the entry point and every handler 'as pure'
  3. If any handler needs side effects: remove 'as pure' from the entry point AND from every handler

Rationale

A call made through the entry point is routed to whichever handler matches the argument's runtime type. The entry point's purity is therefore the promise made about every handler: a non-pure handler would break a pure entry point's promise, and a pure handler behind a non-pure entry point is a claim no caller can ever rely on, because callers only see the entry point. One dispatcher, one purity.

Common causes

  • Dispatcher marked pure but a handler needs side effects
  • Adding a new handler to a pure dispatcher without 'as pure'
  • Marking one handler 'as pure' under a dispatcher that is not pure
  • A sub-type adding a handler to an inherited dispatcher with the other purity

See also

  • E05170: dispatcher handler purity differs from the entry point (this error)
  • E05150: override method missing purity (inheritance context)

Examples

Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.

Fails with E05170: dispatcher handler must match the purity of the dispatcher entry point ('pure' on both or on neither)

#!ek9
defines module error.e05170.bad

  defines class

    BadDispatcher4

      //Dispatcher entry point is PURE
      process() as pure dispatcher
        -> input as Any
        require input?

      //ERROR: Dispatch target is NOT pure
      process()
        -> input as Integer
        require input?

    BadDispatcher4b

      //Dispatcher entry point is NOT pure
      process() as dispatcher
        -> input as Any
        require input?

      //ERROR: Dispatch target is pure
      process() as pure
        -> input as Integer
        require input?

Fixed: Give every handler the purity of the dispatcher entry point

#!ek9
defines module error.e05170.good

  defines class

    GoodDispatcher

      //Dispatcher entry point is pure
      process() as pure dispatcher
        -> input as Any
        require input?

      //Every handler pure too
      process() as pure
        -> input as Integer
        require input?

      process() as pure
        -> input as String
        require input?

    GoodNonPureDispatcher

      //Dispatcher entry point is not pure
      process() as dispatcher
        -> input as Any
        require input?

      //No handler pure either
      process()
        -> input as Integer
        require input?

Questions and answers

These Q&A entries show E05170 and its fix: