Clojure Multimethods by Example

Essentially, these are similar to switch/case logic or, perhaps more similar to a strategy pattern.  defmulti will select a defmethod, to which it will dispatch your call.

From the popular clojure-koans, we have this example:

(defmulti diet (fn [x] (:eater x)))
(defmethod diet :herbivore [a] (str (:name a) " eats veggies."))
(defmethod diet :carnivore [a] (str (:name a) " eats animals"))
(defmethod diet :default [a] (str "I don't know what " (:name a) " eats."))

The defmulti ‘diet’ will select the appropriate defmethod from among the three options by evaluating (fn [x] (:eater x)) for x.

We can see from  (:eater x) that x is supposed to be a map, with an :eater key.  The value for that key will determine which defmethod to call.

So if x contains a value of :herbivore for :eater, then when we call diet, (str (:name a) ” eats veggies.”) will be evaluated.

(diet {:name "Bambi"  :eater :herbivore})
>= "Bambi eats veggies."

Likewise if x contains a value of :carnivore for :eater, then when we call diet,  (str (:name a) ” eats animals.”) will be evaluated.

(diet {:name "Simba" :eater :carnivore})
>= "Simba eats animals."

And the default defmethod will get executed when there is no other match.

That is all.