previous up next
Previous: 3 Lisp方言としてのClojure Up: 特徴 (翻訳開始前) Next: 5 並行処理

4 ランタイムの多態性

Systems that utilize runtime polymorphism are easier to change and extend. Clojure supports polymorphism at 3 levels. First, almost all of the core infrastructure data structures in the Clojure runtime are defined by Java interfaces. Second, Clojure supports the generation of implementations of Java interfaces in Clojure using proxy (see JVM Hosted). The final and primary language construct for polymorphism is the Clojure multimethod.

Clojure multimethods are a simple yet powerful mechanism for runtime polymorphism that is free of the trappings of OO, types and inheritance. The basic idea behind runtime polymorphism is that a single function designator dispatches to multiple independently-defined function definitions based upon some value of the call. For traditional single-dispatch OO languages that value is the type of the 'receiver' or 'this'. CLOS generic functions extend dispatch value to a composite of the type or value of multiple arguments, and are thus multimethods. Clojure multimethods go further still to allow the dispatch value to be the result of an arbitrary function of the arguments. Clojure does not support implementation inheritance.

Multimethods are defined using defmulti, which takes the name of the multimethod and the dispatch function. Methods are independently defined using defmethod, passing the multimethod name, the dispatch value and the function body.

(defmulti encounter (fn [x y] [(:Species x) (:Species y)]))
(defmethod encounter [:Bunny :Lion] [b l] :run-away)
(defmethod encounter [:Lion :Bunny] [l b] :eat)
(defmethod encounter [:Lion :Lion] [l1 l2] :fight)
(defmethod encounter [:Bunny :Bunny] [b1 b2] :mate)
(def b1 {:Species :Bunny :other :stuff})
(def b2 {:Species :Bunny :other :stuff})
(def l1 {:Species :Lion :other :stuff})
(def l2 {:Species :Lion :other :stuff})
(encounter b1 b2)
-> :mate
(encounter b1 l1)
-> :run-away
(encounter l1 b1)
-> :eat
(encounter l1 l2)
-> :fight

Multimethods are in every respect fns, e.g. can be passed to map etc.


previous up next
Previous: 3 Lisp方言としてのClojure Up: 特徴 (翻訳開始前) Next: 5 並行処理
MARUI Atsushi
2013-01-12