Clojure supports run-time polymorphism. The run-time polymorphism is exactly late binding (run-time dispatch) of functions. In many classical object-oriented languages methods (or member functions) are binded to type (class) declaration of variable receiver (or this). (In CLOS you can refer to not only the type declaration but also value of the variable.) On Clojure you can declare run-time dispatch function by defmulti, and define methods which are called by this dispatching. To illustrate:
user=> (defmulti encounter (fn [x y] [(:Species x) (:Species y)]))
user=> (defmethod encounter [:Bunny :Lion] [b l] :run-away) user=> (defmethod encounter [:Lion :Bunny] [l b] :eat) user=> (defmethod encounter [:Lion :Lion] [l1 l2] :fight) user=> (defmethod encounter [:Bunny :Bunny] [b1 b2] :mate) user=> (def b1 {:Species :Bunny :other :stuff}) user=> (def b2 {:Species :Bunny :other :stuff}) user=> (def l1 {:Species :Lion :other :stuff}) user=> (def l2 {:Species :Lion :other :stuff}) user=> (encounter b1 b2) :mate user=> (encounter b1 l1) :run-away user=> (encounter l1 b1) :eat user=> (encounter l1 l2) :fight You can use class, returning the class of the data, as a dispatching function.
user=> (defmulti what-am-i class) user=> (defmethod what-am-i Number [arg] (println arg "is a Number")) user=> (defmethod what-am-i String [arg] (println arg "is a String")) user=> (defmethod what-am-i :default [arg] (println arg "is something else")) user=> (what-am-i 19) 19 is a Number user=> (what-am-i "Hello") Hello is a String user=> (what-am-i true) true is something else Inheritance is not supported in Clojure.
References:
http://clojure.org/runtime_polymorphism
http://java.ociweb.com/mark/clojure/article.html | 実行時ポリモーフィズムはサポートされます.実行時ポリモーフィズムとは関数のレイトバインディング(実行時ディスパッチ)であり,古典的なオブジェクト指向言語ではメンバ関数(メソッド)が変数this(変数receiver)の型定義にバインドされます.(CLOSでは変数の型だけでなく変数の値も参照できます.)Clojureはdefmultiによって実行時ディスパッチ関数を指定し,ディスパッチ先の関数をdefmethodで定義します.次の例を見てください. user=> (defmulti encounter (fn [x y] [(:Species x) (:Species y)])) user=> (defmethod encounter [:Bunny :Lion] [b l] :run-away) user=> (defmethod encounter [:Lion :Bunny] [l b] :eat) user=> (defmethod encounter [:Lion :Lion] [l1 l2] :fight) user=> (defmethod encounter [:Bunny :Bunny] [b1 b2] :mate) user=> (def b1 {:Species :Bunny :other :stuff}) user=> (def b2 {:Species :Bunny :other :stuff}) user=> (def l1 {:Species :Lion :other :stuff}) user=> (def l2 {:Species :Lion :other :stuff}) user=> (encounter b1 b2) :mate user=> (encounter b1 l1) :run-away user=> (encounter l1 b1) :eat user=> (encounter l1 l2) :fight ディスパッチ関数としてデータのクラスを返すclassを使うとこんなことができます. user=> (defmulti what-am-i class) user=> (defmethod what-am-i Number [arg] (println arg "is a Number")) user=> (defmethod what-am-i String [arg] (println arg "is a String")) user=> (defmethod what-am-i :default [arg] (println arg "is something else")) user=> (what-am-i 19) 19 is a Number user=> (what-am-i "Hello") Hello is a String user=> (what-am-i true) true is something else インヘリタンスはサポートされていません. 参考 http://clojure.org/runtime_polymorphism http://java.ociweb.com/mark/clojure/article.html |
Education > Closer to Clojure >