Thank you for your explanation. I also suspect there is some subtle issue with the class file being used by the different constructors.
However, I would be surprised if this behaviour is intended, and that the 'hackery' you proposed is the only, and prefered way of solving this. To better illustrate the core issue, I updated the example slightly as follows: Premise: defrecordissue.arecord and defrecordissue.protocol constitute some library. 1. defrecordissue.arecord defines a record type, and a function that will return an instance of the record: (ns defrecordissue.arecord) (defrecord ARecord []) (defn make-record [] (->ARecord)) 2. defrecordissue.protocol defines a protocol, and extends it to the record type defined in 1. It also defines a public function intended to be used by libraries: (ns defrecordissue.aprotocol (:require [defrecordissue.arecord]) (:import [defrecordissue.arecord ARecord])) (defprotocol AProtocol (afn [this])) (extend-protocol AProtocol ARecord (afn [this] 42)) (defn some-public-fn [] (afn (defrecordissue.arecord/make-record))) 3. defrecordissue.consumer is a consumer of the library, knows nothing of any protocols or records, but only wants to call a function thats part of the public api: (ns defrecordissue.consumer (:require [defrecordissue.aprotocol])) (defrecordissue.aprotocol/some-public-fn) This fails with the same root cause. I've created a new branch for this in the GitHub repo. https://github.com/ragnard/defrecordissue/tree/more-realistic /Ragge On Thursday, 18 April 2013 12:19:35 UTC+1, Andrew Sernyak wrote: > > I guess extend-type does changes only to generated java class and the var > defrecordissue.arecord->ARecord > contains the 'old' version of ARecord constructor. Obviously it would be > weird for defprotocol to change the variable in another namespace. > Especially when you can extend a record from anywhere. > > So If you want to create a record that implements your protocol via var > from record namespace, you should do some hackery to update that variable. > I've done a pull-request for you, but using direct constructor will be more > idiomatic > > ; >> ; this won't work unless you update manualy a variable ->ARecord in the >> namespace >> ; >> ;(defrecordissue.aprotocol/afn (defrecordissue.arecord/->ARecord)) >> ; >> ; like >> (defmacro from-ns[nmsps & body] >> "launches body from namespace" >> `(binding >> [*ns* (find-ns ~nmsps)] >> (eval >> (quote (do ~@body))))) >> (from-ns 'defrecordissue.arecord >> (import '(defrecordissue.arecord.ARecord)) >> (alter-var-root >> ('->ARecord (ns-publics 'defrecordissue.arecord)) >> (fn[x] (fn[] (new ARecord))))) >> (println (defrecordissue.aprotocol/afn >> (defrecordissue.arecord/->ARecord))) >> ; 42 > > > ndrw > -- -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.