Clojure’s multimethods allow us to define hierarchies to support whatever relationships your domain requires, including multiple inheritance. These hierarchies are defined in terms of relations between named objects (keywords or symbols) and classes.
“Hierarchies” being plural is no accident: you can have more than
one hierarchy. There’s the global (and default) hierarchy and ones you can
create as needed via
addition, hierarchies and multimethods are in no way restricted to a
single namespace: you can extend a hierarchy (through
derive) or a multimethod (via
defmethod) from any namespace—not necessarily
the one in which they were defined.
The global hierarchy being shared, access to it is more guarded. Namely, non-namespaced keywords (or symbols) cannot be used in the global hierarchy. This helps prevent two innocent libraries from stepping on each other’s toes by independently choosing to use the same keyword to represent different semantics.
You define a hierarchical relation with
(derive ::checkbox ::checkable) ;= nil (derive ::radio ::checkable) ;= nil (derive ::checkable ::input) ;= nil (derive ::text ::input) ;= nil