Why shouldn't multimethods in Clojure simply be replaced by cond expressions?
I was inspired to ask after looking at the simple examples of multimethods in Ch. 5 of Russ Olsen's book Getting Clojure.
In a reply to a similar question (Performance of multimethod vs cond in Clojure), user Daniel Compton says
Multimethods allow for open extension; others can extend your multimethod dispatching on arbitrary expressions. Cond expressions are closed to extension by others or even your own code.
But it's not at all clear to me what "open extension" and "closed to extension" mean in this context, since it seems to me that both multimethods and cond expressions can be edited or expanded quite easily.
So... why shouldn't multimethods in Clojure simply be replaced by cond expressions?
Or, equivalently, how or when exactly can using multimethods be better or more elegant than using cond?
The key point here is "allow for open extension". Anyone can add new
branches for your multimethods - a cond
is hard-coded: new dispatches
must be added to the cond
code in place.
Let's say: you have some widgets and you want to draw them. The widgets have
a :type
and you want to dispatch how to draw
on that type.
Writing a big cond
for all the widgets you know about will work. But now
for each new widget, you have to touch your cond
source code and modify it.
This can be perfectly fine for e.g. an actual application, that does not need
extension.
Doing the same with multimethods, anyone can implement a draw
for their
widget. So you don't know all of them when writing your code. This makes
it a way better (or even mandatory) approach for e.g. libraries.
Now imagine, that you have decided for the cond
approach in a library
you are writing. Anyone with a new widget now must write their own
draw
, dispatch for their draws first, then call your draw
. Also they
would have to make sure, their draw
is called everywhere, where your
draw
was called to have it working (which often is just impossible in
a clean way).
One popular example for a multimethod directly in the Clojure core is
print-method
.
By that anyone can implement a "serialization" for their type and play
nicely.
Other honourable mentions for examples to look at are clojure.test and integrant.
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