Polymorphism lets one operation choose different implementations according to an input’s type or another dispatch criterion. Clojure separates inheritance from interface declaration and supports an “a-la carte” approach through interfaces, protocols, and multimethods. section 15.0
A small program can dispatch on metadata with type and condp, but this becomes difficult to extend as types multiply. Multimethods let applications add implementations incrementally without changing existing code. section 15.2
Dispatching contact formatting
Define a dispatch function with (defmulti print-contact type), then add methods for :person, :business, String, and :default. A person prints as “Mr John,” a business as “Manning (Marjan),” a string as “Contact: Mr. Renzo,” and nil uses the default format. section 15.2
Choose the dispatch technique according to the shape and growth of the problem:
- Use metadata with type for simple, fixed sets of types. section 15.2
- Prefer multimethods when types are added frequently or in large numbers. section 15.2
- Avoid accumulating instance? checks in cascading conditionals; consider protocols or multimethods instead. section 15.2
(class []) ; #1
;; clojure.lang.PersistentVector
(class "") ; #2
;; java.lang.String
(class #()) ; #3
;; user$eval25$fn__26
(class nil) ; #4
;; nil
(type {:a 1}) ; #5
;; clojure.lang.PersistentArrayMap
(type (with-meta {:a 1} {:type :custom})) ; #6
;; :custom
Inspect class and type results for vectors, strings, functions, nil, maps, and metadata-tagged values before choosing a dispatch strategy. section 15.0








