Function dispatch, loosely speaking,
allows a function to be calculated by different code
based on the manner in which it is called.
Of course, this description also applies to conditional evaluation,
but function dispatch tends to be more declarative, modular, etc.
Clojure supports various forms of function dispatch, based on argument
Conditional evaluation can achieve many of the same results as function dispatch.
For example, the
macro can be used to evaluate different code,
based on arbitrary criteria.
However, this approach has some significant drawbacks:
- The code resides in a single function,
complecting selection and evaluation.
- The function must be edited whenever a case
needs to be added, modified, or removed.
- The approach is imperative, rather than declarative.
Consequently, the approaches described below are generally preferable.
Clojure functions can be defined in multiple sections,
each of which handles a different arity
(ie, number of arguments), eg:
( ... )
([x] ... )
([x y] ... )
([x y & more] ... ) )
support statically-defined single dispatch,
based on the class of the receiving object.
See the Java, etc.
page and the
section (below) for more information.
based on arbitrary criteria:
A Clojure multimethod is a combination of a dispatching function
and one or more methods.
When a multimethod is defined, using
defmulti, a dispatching function must be supplied.
This function will be applied to the arguments to the multimethod
in order to produce a dispatching value.
The multimethod will then try to find the method associated with the dispatching value
or a value from which the dispatching value is derived. ...
Although multimethods can be (and historically, were) used
to dispatch based the type of the first argument (eg, the type of the receiving Java object),
now provide a more declarative, extensible, and efficient solution
for this use case.
However, multimethods are still useful,
because they can handle many other types of dispatch.
support single dispatch,
based on the type (eg,
) of a function's first argument.
So, like Java's interfaces
they handle the common case of dispatching on an object's type.
However, protocols also allow dynamic creation and extension
and sidestep the requirement for class hierarchies, etc.
This wiki page is maintained by Rich Morin
an independent consultant specializing in software design, development, and documentation.
Please feel free to email
comments, inquiries, suggestions, etc!