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

Popular posts from this blog

assembly - 8086 TASM: Illegal Indexing Mode -

Java, LWJGL, OpenGL 1.1, decoding BufferedImage to Bytebuffer and binding to OpenGL across classes -

javascript - addthis share facebook and google+ url -