On Wed, May 20, 2009 at 8:44 AM, pmf <phil.fr...@gmx.de> wrote:
>
> On May 20, 4:47 am, Per <nondual...@gmail.com> wrote:
>> ;; The macro
>> (defmacro def-fields [name  tgs]
>>   `(defstruct ~name ~@(map #(symbol (str ":" %)) tgs))
>> )
>
> If you replace the call to 'symbol' with a call to 'keyword', it works
> (I think this is what you intended).

I don't think its that simple. I still get the error if I change it to
a call to 'keyword'. The problem I believe is that because def-fields
is a macro, the arguments are not evaluated, so in the macro, tgs is
bound to the symbol 'tags _not_ the value of tags as defined above the
macro.

I've encountered this myself several times, I'm not sure what the
idiomatic way of handling this is but this change demonstrates what I
am talking about:

user> (def tags '("name" "age"))
#'user/tags
user> (defmacro def-fields [name tgs] `(defstruct ~name ~@(map
#(symbol (str ":" %)) tgs)))
#'user/def-fields
user> (macroexpand-1 '(def-fields fs tags))
; Evaluation aborted.
user> (defmacro def-fields [name tgs] `(defstruct ~name ~(.get
(ns-resolve *ns* tgs))))
#'user/def-fields
user> (macroexpand-1 '(def-fields fs tags))
(clojure.core/defstruct fs ("name" "age"))

In my redefinition of the macro, I first resolve the symbol 'tags to
get the Var, and then I get the value of the Var. This indeed returns
the value of tags, but again, I'm not sure its the nicest solution.
The downside here is that now you can't pass in a literal:

user> (macroexpand-1 '(def-fields fs ("name" "age")))

However, if you put in some logic into your macro, you can get both:

(defmacro def-fields [name tgs]
  `(defstruct ~name ~@(map #(symbol (str ":" %))
                                          (if (symbol? tgs)
                                             (.get (ns-resolve *ns* tgs))
                                             tgs))))

I think this yields what you want:

user> (macroexpand-1 '(def-fields fs ("name" "age")))
(clojure.core/defstruct fs :name :age)
user> (macroexpand-1 '(def-fields fs tags))
(clojure.core/defstruct fs :name :age)


/mike.

--~--~---------~--~----~------------~-------~--~----~
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
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