interface - Mixing definterface and defprotocol -
i try implement interface representing arithmetic expressions. interface used java-side whole logic on clojure.
having:
(defprotocol extendsexpression (totree [this])) (extend-type string extendsexpression (totree [this] (symbol this))) (extend-type number extendsexpression (totree [this] this)) (definterface expression (totree [])) (defrecord expression1 [^string oper arg] expression (totree [this] (list (symbol oper) (totree arg)))) (defrecord expression2 [^string oper arg1 arg2] expression (totree [this] (list (symbol oper) (totree arg1) (totree arg2)))) (defrecord expression3 [^string oper arg1 arg2 arg3] expression (totree [this] (list (symbol oper) (totree arg1) (totree arg2) (totree arg3)))) i try use as:
(totree (expression3. "+" "a" "b" (expression2. "*" "c" "d"))) but i'm getting:
illegalargumentexception no implementation of method: :totree of protocol: #'user/extendsexpression found class: user.expression3 clojure.core/-cache-protocol-fn (core_deftype.clj:541) why clojure tries call totree of extendsexpression expression3? expect expression3 call totree method of expression interface.
ok, got ;)
(defprotocol extendsexpression (to-tree [this])) (extend-type string extendsexpression (to-tree [this] (symbol this))) (extend-type number extendsexpression (to-tree [this] this)) (definterface expression (totree [])) (defrecord expression1 [^string oper arg] extendsexpression (to-tree [this] (list (symbol oper) (to-tree arg))) expression (totree [this] (to-tree this))) (defrecord expression2 [^string oper arg1 arg2] extendsexpression (to-tree [this] (list (symbol oper) (to-tree arg1) (to-tree arg2))) expression (totree [this] (to-tree this))) (defrecord expression3 [^string oper arg1 arg2 arg3] extendsexpression (to-tree [this] (list (symbol oper) (to-tree arg1) (to-tree arg2) (to-tree arg3))) expression (totree [this] (to-tree this))) (to-tree (expression3. "+" "a" "b" (expression2. "*" "c" "d"))) ;=> (+ b (* c d)) and records implements expression interface, can call them java easily:
(.totree (expression3. "+" "a" "b" (expression2. "*" "c" "d"))) ;=> (+ b (* c d)) just check interfaces expression3 implements:
(-> expression3 clojure.reflect/reflect :bases pprint) #{clojure.lang.ihasheq java.io.serializable clojure.lang.ikeywordlookup clojure.lang.ipersistentmap clojure.lang.irecord java.lang.object user.extendsexpression clojure.lang.iobj clojure.lang.ilookup user.expression java.util.map}
Comments
Post a Comment