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