Polymorphism
Web Development with Clojure, Third Edition — by Dmitri Sotnikov, Scot Brown (78 / 107)
👈 Dynamic Variables | TOC | What About Global State? 👉
One useful aspect of object orientation is polymorphism; while polymorphism happens to be associated with that style, it’s in no way exclusive to object-oriented programming. Clojure provides two common ways to achieve runtime polymorphism. Let’s look at each of these in turn.
Multimethods
Multimethods provide an extremely flexible dispatching mechanism using a selector function associated with one or more methods. The multimethod is defined using defmulti, and each method is defined using defmethod. For example, if we had different shapes and we wanted to write a multimethod to calculate the area, we could do the following:
(defmulti area :shape)
(defmethod area :circle [{:keys [r]}]
(* Math/PI r r))
(defmethod area :rectangle [{:keys [l w]}]
(* l w))
(defmethod area :default [shape]
(throw (Exception. (str "unrecognized shape: " shape))))
(area {:shape :circle :r 10})
=> 314.1592653589793
(area {:shape :rectangle :l 5 :w 10})
=> 50
Preceding, the dispatch function uses a keyword to select the appropriate method to handle each type of map. This works because keywords act as functions and when passed a map return the value associated with them. The dispatch function can be as sophisticated as…