Clojure defprotocol & defrecord

以前、 defmulti でポリモーフィズムを実現していた例を試し書きしたが、
別の書き方。

(defprotocol Shape
  "面積が計算できる"
  (area [shape]))

(defrecord Circle [radius]
  Shape
    (area [circle] (* (. Math PI) (* (:radius circle) (:radius circle)))))

(defrecord Rect [wd ht]
  Shape
    (area [rect] (* (* (:wd rect) (:ht rect)))))

;; 本当は、文字列は面積計算できないが、まぁ気にするな
(extend-type java.lang.String
  Shape
  (area [string] (.length string)))

(def circle-1 (Circle. 2))
(def rect-1 (Rect. 2 3))

(println (map area [circle-1 rect-1 "xxxx"]))

1.2から書けるようになった模様。インタフェースとその実装の関係が明記できる。
パフォーマンスが defmulti よりも良いらしい。defprotocol も defmulti も ポリモーフィズムの機構であって、パターンマッチングではない。パターンマッチングを、ライブラリ化している人はいるみたい。

https://github.com/swannodette/match