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

Reply via email to