It sounds like he's going to be given the list of keywords by the
user, and won't have it as a compile-time literal. Maybe he's load'ing
a .clj file, for example, that someone will write in the future. Maybe
you can combine our two approaches to get something that works and
isn't ugly, but I'm having a hard time finding it. (def) requires a
symbol as its first argument, and is a macro so needs it at compile
time. The best I can do is:

(defmacro buildfn [name]
        `(defn ~name [arg#] 10))
(doseq [k '[a b c]]
        (eval `(buildfn ~k)))

On Sep 10, 4:20 pm, Robert McIntyre <r...@mit.edu> wrote:
> Why not explicitly feed the macro the keyword map if that is what it wants?
>
> (defmacro ultra-synth [prefix keywords]
>   (let [symbols (map (comp symbol name)  keywords)
>         fn-names (map (comp symbol
>                             (partial str prefix) name) keywords)
>         defn-forms (map
>                     (fn [fn-name symbol]
>                       `(defn ~fn-name [n#]
>                          (= n# ~symbol)))
>                     fn-names symbols)]
>     `(do ~...@defn-forms)))
>
> thunderbolt.play> (def a 5)
> #'thunderbolt.play/a
> thunderbolt.play> (def b 5)
> #'thunderbolt.play/b
> thunderbolt.play> (ultra-synth "hi" [:a :b])
> #'thunderbolt.play/hib
> thunderbolt.play>  (hia 5)
> true
>
> --Robert McIntyre
>
> On Fri, Sep 10, 2010 at 6:17 PM, Alan <a...@malloys.org> wrote:
> > PS this is super-ugly and I'm always embarrassed when I find myself
> > using eval in a lisp. While this works, I'd love it if someone could
> > tell me how to do it with macros.
>
> > On Sep 10, 3:07 pm, Alan <a...@malloys.org> wrote:
> >> I see. It's hard to imagine how this could work, since macros don't
> >> have access to runtime data like the value of x in your example.
> >> Perhaps you're better off writing a function that returns a closure,
> >> and iteratively def'ing those?
>
> >> user=> (defn make-kw-fn [kw]
> >>          #(= kw %))
> >> #'user/make-kw-fn
> >> user=>
> >> (def kws [:a :b])
> >> #'user/kws
> >> user=>
> >> (eval (cons 'do (map #(list 'def (symbol (str "test-" (name %))) (make-
> >> kw-fn %)) kws)))
> >> #'user/test-b
> >> user=> (test-b :a)
> >> false
> >> user=> (test-b :b)
> >> true
>
> >> On Sep 10, 1:37 pm, icemaze <icem...@gmail.com> wrote:
>
> >> > Alan, thank you for your reply.
> >> > Unfortunately your solution is very similar to mine and it suffers
> >> > from the same problem (maybe I'm using it incorrectly, I don't know).
> >> > If I write:
>
> >> >   (doseq [x '(:a :b)]
> >> >     (make-fn x))
>
> >> > it defines a single function "synthetic-x". Is there a way to make
> >> > this work? I tried everything but both eval and var-get don't work for
> >> > local bindings.
>
> >> > Thanks again.
>
> > --
> > 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