Multimethods aren’t magic (nor mutable)
What does this code display?
(defmulti foo first) (def print-foo (comp println foo)) (defmethod foo :a [x] "it's a 'a'!") (print-foo [:a])
Nothing, it raises an error: it doesn’t know what to do with the dispatch value :a
. The value of foo
is captured when comp
is called.
The thing to keep in mind is that defmethod
mutates the var, not the multimethod itself — which is of course immutable. The solution is to pass the var instead of the multimethod to comp
:
(defmulti foo first) (def print-foo (comp println #'foo)) (defmethod foo :a [x] "it's a 'a'!") (print-foo [:a]) ; prints "it's a 'a'!"
Update or maybe it’s a code smell that you should use a macro instead of a function.
Update 2 Clojure’s father (Rich Hickey) says : the correct thing to do is use the var
.