Never mind Q2, I didn't understand the question correctly. Jonathan
On Mon, May 9, 2011 at 5:21 PM, Jonathan Fischer Friberg < odysso...@gmail.com> wrote: > Q1 This macro captures the correct namespace: > > (defmacro new* [type-name-as-symbol & args] > `(clojure.lang.Reflector/invokeConstructor > (ns-resolve ~*ns* ~type-name-as-symbol) > (to-array '~args))) > > Q2 Backquote ` is unnecessary for symbols, use standard quote ' > > Q3 Answer to 1 fixes this > > Q4 I'm not entirely sure, but roughly: > . means namespace (or class!) > / means field in namespace (or class!) > That is why you have to use . for records, since records generate classes. > > Q5 I guess? > > Jonathan > > > On Mon, May 9, 2011 at 2:00 PM, Simon Katz <nomisk...@gmail.com> wrote: > >> I'm trying to implement a function similar to new, but where >> the type is not known at compile time -- so I want to evaluate >> the first argument. >> >> With the help of Google, I found the approach used in new* >> below: >> >> (ns dynamic-new) >> >> (defn new* [type-name-as-symbol & args] >> (clojure.lang.Reflector/invokeConstructor >> (resolve type-name-as-symbol) >> (to-array args))) >> >> In simple situations it works ok: >> >> (ns my-namespace >> (:refer dynamic-new)) >> >> (defrecord MyRecord [a b c]) >> >> (= (new MyRecord 1 2 3) >> (new* 'MyRecord 1 2 3) >> (new* 'my-namespace.MyRecord 1 2 3)) >> => true >> >> (= (new java.util.Date 0 0 1) >> (new* 'java.util.Date 0 0 1)) >> => true >> >> But there's a problem with unqualified symbols. >> Continuing with definitions in my-namespace... >> >> (defn instantiate-qualified [] >> (new* 'my-namespace.MyRecord 1 2 3)) >> >> (defn instantiate-unqualified [] >> (new* 'MyRecord 1 2 3)) >> >> (defn both-funs-same? [] >> (= (instantiate-qualified) >> (instantiate-unqualified))) >> >> (both-funs-same?) >> => true >> >> OK -- no surprises above. >> >> But... >> >> (ns another-namespace) >> (try (do (my-namespace/instantiate-unqualified) >> "succeeded") >> (catch Exception e "failed")) >> => "failed" >> >> In another-namespace, the call of my-namespace/instantiate-unqualified >> fails because there is no data type or class named MyRecord in that >> namespace. >> >> And... >> >> (ns a-namespace-with-a-different-MyRecord) >> (defrecord MyRecord [a b c]) ; two MyRecords in different >> namespaces >> (my-namespace/instantiate-unqualified) >> => #:a-namespace-with-a-different-MyRecord.MyRecord{:a 1, :b 2, :c >> 3} >> >> So, the function my-namespace/instantiate-unqualified has created >> an instance of a-namespace-with-a-different-MyRecord.MyRecord. >> This could be a source of confusing bugs. >> >> Now my questions: >> >> Q1. Is this basically the right approach, or is there some other >> way to implement new*? >> >> Q2. I can use syntax-quote to qualify a symbol at read time: >> (defn instantiate-unqualified [] >> (new* `MyRecord 1 2 3)) >> Is that the right way to go? >> >> Q3. It might be a good idea to check in new* that the symbol passed >> to it is qualified. In combination with the use of syntax-quote, >> this might be a good solution. Is there a way to check for this? >> (Perhaps checking whether the symbol's name contains a "."? But >> (a) that's slow and (b) I'm not sure it's good enough.) >> >> I had thought that I might be able to use the namespace function >> to check this, because >> (namespace 'my-namespace/foo) => "my-namespace" >> but unfortunately >> (namespace 'my-namespace.MyRecord) => nil >> >> Q4. Given that symbols containing "." are qualified, is >> (namespace 'my-namespace.MyRecord) => nil >> correct behaviour? >> (I think I don't fully understand symbols containing "." but >> not "/".) >> >> Q5. I've seen the phrase "fully-qualified symbol" used in a few >> places. Does this simply mean "qualified symbol"? If there >> is such a thing as a partially-qualified symbol, checking >> that a symbol is qualified may not help. >> >> Simon >> >> -- >> 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 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