Clojure, like many other functional languages, uses free typing to provide simple ways to implement parametric polymorphism . This basically means that one method can be constructed in such a way that it does not care about the types of values that are given to it.
Take, for example, the concat method. It takes any number of arguments of different forms and puts them on one list:
user=> (concat [:a :b] nil [1 [2 3] 4]) (:a :b 1 [2 3] 4)
Since it is not necessary to declare input of parameters for the arguments, concat can be written in such a way that you can provide an argument of any type (vector, function, keyword, string, etc.), and it will act on them in a similar way.
Clojure multimethods allows you to support this concept on Java objects, which can be completely different structures (i.e. taxonomies), using metadata or other properties to determine the appropriate way to deal with this argument. See the following example (taken from defmulti ):
(defmulti greeting (fn[x] (x "language"))) (defmethod greeting "English" [params] (str "Hello! " (params "id"))) (defmethod greeting "French" [params] (str "Bonjour! " (params "id"))) =>(greeting {"id" "1", "language" "English"}) "Hello! 1" =>(greeting {"id" "2", "language" "French"}) "Bounjour! 2"
The greeting method returns the value "language" from the card that matches the "English" or "French" method, which returns the correct corresponding value. I hope you can see how this concept could potentially be applied to almost any type of data or structure of objects. This powerful polymorphism idea is what Clojure developers are trying to show on the rationale page.
source share