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