
Clojure multi-methods - puredanger
http://tech.puredanger.com/2010/08/21/clojure-multi-methods/
======
barrkel
I would actually object to describing Clojure's multimethods as being
multimethods, especially in the CLOS sense of the term. Clojure's multimethods
are more like a clumsy, dynamic version of functional pattern matching, with a
classification predicate applied to the arguments to select the target method.
In this sense, it's the programmer - the supplier of the dispatching function
- who has the job of doing the dispatching. This trickiness of this
dispatching is probably the motivation behind the CLOS language feature, but
Clojure foists it on the developer.

What would more normally be described as multimethods is the dynamic
equivalent of a static language's implementation of overload resolution.
Overload resolution has subtle semantics in languages that support it, and is
surprisingly difficult to get right, as it has competing design forces: the
flagging of ambiguity, versus inferring what the user - the customer - wants.

There are two steps in both overload resolution and multimethod dispatch:
discovery of the set of applicable methods, and then the sorting of those
methods by how specific they are to the argument types. Every parameter type
in the winning method needs to be as specific, or more specific, for that
argument type, than every other method's parameter type. The single most
specific method, if any, is chosen. (The OO case of inheritance is just a
special case of specificity.)

There may be no applicable methods, in which case it's a simple error. But the
case of ambiguity is fraught with difficulties, because users generally prefer
their code to do what they mean, and inferring that from what they say - the
methods they declare - can be difficult. Suppose your language supports
implicit conversions of values to supertypes, or to supported interfaces.
Overload resolution forces you to specify a priority here - which method to
prefer in the case where the relevant parameter type is alternately one or the
other - or to produce an error - i.e. telling the customer that they're wrong.
Bring other language features, like user-defined conversions, variant types,
untyped parameters, multiple inheritance, etc., and you can can quickly find
yourself in a mess.

~~~
puredanger
Clojure actually does support (multiple, open) type hierarchies (with
preferences) for dispatching on type. This example just doesn't use them. Lots
more info here: <http://clojure.org/multimethods>

Another solution is provided in Clojure 1.2's protocols which are similar but
different: <http://clojure.org/protocols>

~~~
barrkel
Ah, I see. I had thought that a single dispatcher value was required; but I
see that a list of them is acceptable, and Clojure then uses the more regular
means on _that_ , rather the original list of arguments. Then, the point of
the dispatching function - which is what it's called in the Clojure docs - is
rather a classifier function, rather than dispatcher.

------
puredanger
Make sure to check out the followup to this article re Perl 6:
[http://blogs.perl.org/users/tyler_curtis/2010/08/age-
discrim...](http://blogs.perl.org/users/tyler_curtis/2010/08/age-
discrimination-in-perl-6-using-subsets-and-multiple-dispatch.html)

and the HN discussion: <http://news.ycombinator.com/item?id=1624027>

------
puredanger
And this follow-up in Python:
[http://codeblog.dhananjaynene.com/2010/08/clojure-style-
mult...](http://codeblog.dhananjaynene.com/2010/08/clojure-style-multi-
methods-in-python/)

