Clojure Programming/Examples/API Examples/Multimethod
This page list examples of how to create Multi-Methods with the Clojure API.
defmulti
edit(defmulti area :Shape)
(defn rect [wd ht] {:Shape :Rect :wd wd :ht ht})
(defn circle [radius] {:Shape :Circle :radius radius})
(defmethod area :Rect [r]
(* (:wd r) (:ht r)))
(defmethod area :Circle [c]
(* (. Math PI) (* (:radius c) (:radius c))))
(defmethod area :default [x] :oops)
(def r (rect 4 13))
(def c (circle 12))
(area r)
-> 52
(area c)
-> 452.3893421169302
(area {})
-> :oops
This is an example of using multi-methods without using a hierarchy:
(defmulti rand-str
(fn [] (> (rand) 0.5)))
(defmethod rand-str true
[] "true")
(defmethod rand-str false
[] "false")
(for [x (range 5)] (rand-str))
-> ("false" "false" "true" "true" "false")
defmethod
edit(defmulti fib int)
(defmethod fib 0 [_] 1)
(defmethod fib 1 [_] 1)
(defmethod fib :default [n] (+ (fib (- n 2)) (fib (- n 1))))
user=> (map fib (range 10))
(1 1 2 3 5 8 13 21 34 55)
Another example where the defmulti takes arguments and evaluates them before calling the defmethod
(defmulti multi-fun
(fn [x y] (+ x y)))
(defmethod multi-fun 3 [x y]
(print "Specialisation 3"))
(defmethod multi-fun :default [x y]
(print "Generic " (+ x y)))
user=> (multi-fun 1 2)
Specialisation 3
user=> (multi-fun 3 4)
Generic 7