Reading — step 1 of 5
Learn
~1 min readPolymorphism
Multimethods dispatch on whatever you want — type, shape, value, computed key. More flexible than Java-style single dispatch.
(defmulti area :shape)
(defmethod area :circle [s]
(* Math/PI (:radius s) (:radius s)))
(defmethod area :square [s]
(* (:side s) (:side s)))
(defmethod area :rectangle [s]
(* (:width s) (:height s)))
(defmethod area :default [s]
(throw (Exception. (str "unknown shape: " (:shape s)))))
(area {:shape :circle :radius 5}) ; 78.54
(area {:shape :square :side 4}) ; 16
The :shape keyword is used as a dispatch function — its result picks the method.
Any function works as the dispatch:
(defmulti pay (fn [employee] (:type employee)))
(defmulti format-amount (fn [amount currency] currency))
Dispatch on multiple values:
(defmulti combine (fn [a b] [(class a) (class b)]))
(defmethod combine [String String] [a b] (str a b))
(defmethod combine [Number Number] [a b] (+ a b))
Hierarchies let you organize dispatch values:
(derive ::admin ::user) ; admin is-a user
(defmethod greet ::user [u] (str "Hello, " (:name u)))
;; admin instance dispatches to ::user method (since admin derives from user)
Use multimethods when type-class-like behavior with open extension matters more than performance. For tighter, more focused polymorphism, use protocols (next lesson).
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…