Both pattern matching and polymorphic dispatch are available.
Two forms of polymorphic sending are dots and protocols.
leontalbot , ( , ). , , multimethod .
:
; Declare multimethod:
(defmulti get-length class)
; Provide implementations for concrete types:
(defmethod get-length java.lang.String [str] (.length str))
(defmethod get-length java.lang.Number [num] (.length (str num)))
; Call it for String:
(get-length "Hello") ;=> 5
; Call it for a Number (works because Long is a subtype of Number):
(get-length 1234) ;=> 4
, , . , :
(defn choose-impl [in]
(cond
(is-sorted? in) :sorted
(< (count in) 10) :bubble
:else :quicksort))
(defmulti my-sort choose-impl)
(defmethod my-sort :sorted [in] in)
(defmethod my-sort :bubble [in] (my-bubble-sort in))
(defmethod my-sort :quicksort [in] (my-quicksort in))
, , , , , .
- , , Java OO. , , .
; Protocol specification:
(defprotocol my-length (get-length [x]))
; Records can implement protocols:
(defrecord my-constant-record [value]
my-length
(get-length [x] value))
; We can "extend" existing types to support the protocol too:
(extend-protocol my-length
java.lang.String
(get-length [x] (.length x))
java.lang.Long
(get-length [x] (.length (.toString x))))
; Now calling get-length will find the right implementation for each:
(get-length (my-constant-record. 15)) ;=> 15
(get-length "123") ;=> 3
(get-length 1234) ;=> 4
, core.match:
(doseq [n (range 1 101)]
(println
(match [(mod n 3) (mod n 5)]
[0 0] "FizzBuzz"
[0 _] "Fizz"
[_ 0] "Buzz"
:else n)))