Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Clojure multi-methods (puredanger.com)
43 points by puredanger on Aug 21, 2010 | hide | past | favorite | 5 comments


Make sure to check out the followup to this article re Perl 6: http://blogs.perl.org/users/tyler_curtis/2010/08/age-discrim...

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


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.


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


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.





Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: