I'm a Clojure novice and was looking for some concrete examples of when to use protocols and when to use multimethods. I know that protocols are generally geared towards creating a type hierarchy and typical OOP things, that they were added to the language after multimethods, and that protocols generally have better performance so my question is this:
Are protocols meant to replace multimethods? If not, could you give me an example where I would use multimethods instead of protocols?
Protocol and multimethods are complementary and intended for slightly different use cases.
In general, my advice is to use protocols unless you have a specific case that requires multimethods.
A case where you could require multimethods is something like the following:
(defn balance-available? [amount balance] (> balance amount))
(defmulti withdraw balance-available?)
(defmethod withdraw true [amount balance]
(- balance amount))
(defmethod withdraw false [amount balance]
(throw (Error. "Insufficient balance available!")))
Note that you can't use protocols here for both of the following reasons:
Multimethods are more powerful and more expensive,
use protocols when they are sufficient but if you need to dispatch based on the phase of the moon as seen from mars then multimethods are your best choice.
Protocols exist to allow the simple stuff to stay simple and provide a way for clojure to generate very much the same bytecode that the equivalent java would. It seems that most people use protocols most of the time. I use multimethods when I need to dispatch on more than one argument, though I have to admit that this has only come up once, and full isa
hierarchies are used even less often (by me). so in short use Multimethods when you need them
the best example In my expierence is right at the start, in core.clj
As mention by Arthur, multimethods are more powerful and more expensive. Indeed, protocols can be thought of as a special case of mutlimethods where the dispatch function is class
. Of course, this is not really the case as protocols are more than that.
If you need to dispatch on something other than the class of the first argument, you'll need to use a multimethod, or redesign. Dispatching on type is a good use case for protocols.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With