defmethod
(defmethod name dispatch-value [params...] body...)
Stores a method lambda in the multimethod's table under dispatch-value; the parameters
destructure, map patterns included. On a call, an exact hit against the dispatch value applies
directly. Otherwise the dispatcher searches every method the value descends from through the
multimethod's hierarchy: the strictly most specific wins, prefer-method breaks the remaining
ties, and an unbroken tie signals Multiple methods ....
Dispatch values compare like map keys, by =, so a vector dispatch value hits its method
directly. A dispatch value
may name a host class (String, Number, java.util.Map,
clojure.lang.IPersistentVector, ...) and stores under the keyword class answers for it,
so class multis dispatch to it. A throwable class (IllegalArgumentException,
clojure.lang.ExceptionInfo) or a stream class (java.io.StringWriter, java.io.Writer,
java.io.Reader) stores under its name as a keyword, the one class answers for an exception
or a stream, and the search follows the superclass chain like the oracle's Java inheritance:
a NumberFormatException reaches an IllegalArgumentException method ahead of an
Exception one. Any other host class (java.io.File, java.util.AbstractList) stores under
its class object, the one class answers for a host object (interpreter and JVM), and the
search follows its Java supers the same way: an ArrayList reaches a java.util.AbstractList
method ahead of a java.util.List one. Such a dispatch value is host interop, so the
defmethod fails at run time on wasm. A true nil maps onto the (:C%NIL) marker
(no table ever keys on nil), so a literal :nil dispatch value answers only a :nil
method, like the oracle, and
Object matches every value past the search but ahead of the default.
Deviation: every numeric class spelling merges into :number, where the oracle tells Long
from Double.