Multimethods aren’t magic (nor mutable)

mistakes — cgrand, 28 May 2008 @ 17 h 55 min

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.

(c) 2017 Clojure and me | powered by WordPress with Barecity