Whenever I make a macro like this, I pass the symbol to be captured as an argument to the macro. Any collisions would be more explicit and less surprising.
On Mon, Jul 1, 2013 at 11:21 AM, Baishampayan Ghose <b.gh...@gmail.com>wrote: > Hi, > > What you need is called an anaphoric macro (via symbol capture). > Clojure makes it hard to do a symbol capture in macros since it > qualifies all symbols automatically unless you use the auto gensym > feature. This is done for hygiene purposes and to avoid any unintended > side-effects. > > However indeed, it's possible to create such a macro in Clojure. > > Behold - > > (defmacro test-it [addend & body] `(let [~'foo (+ ~addend 1)] ~@body)) > ;; notice the ~' in front of foo. > > (macroexpand-1 '(test-it 1 (println foo))) > ;=> (clojure.core/let [foo (clojure.core/+ 1 1)] (println foo)) > > Please apply caution before using this feature; document the symbol to > be captured sufficiently. > > Hope that helps. > > Regards, > BG > > On Mon, Jul 1, 2013 at 7:44 PM, Sean Johnson <belu...@acm.org> wrote: > > Hello, > > > > If a macro calculates something and wants to make that result available > to > > the body, what's the right way to do that? So far I've tried these ways > > which don't work (this is not really my macro, it's just a simplified > > example to demonstrate the issue): > > > > 1) lexical scope doesn't work, the symbol gets qualified > > > > (defmacro test-it [addend & body] `(let [foo (+ ~addend 1)] ~@body)) > > > > => (test-it 3 (println foo)) > > CompilerException java.lang.RuntimeException: Can't let qualified name: > > fcms.app/foo, compiling:(NO_SOURCE_PATH:1:1) > > > > => (macroexpand '(test-it 3 (println foo))) > > (let* [fcms.app/foo (clojure.core/+ 3 1)] (println foo)) > > > > > > 2) autogen'ed lexical scope doesn't work, the body doesn't know what the > > autogen'ed symbol will be called > > > > (defmacro test-it [addend & body] `(let [foo# (+ ~addend 1)] ~@body)) > > > > => (test-it 1 (println foo)) > > CompilerException java.lang.RuntimeException: Unable to resolve symbol: > foo > > in this context, compiling:(NO_SOURCE_PATH:1:12) > > > > => (macroexpand '(test-it 3 (println foo))) > > (let* [foo__5755__auto__ (clojure.core/+ 3 1)] (println foo)) > > > > > > 3) an interned var partially works, if the macro and its use are all in > one > > namespace, but not if not, it fails to intern the var > > > > (defmacro test-it [addend & body] `(do (def foo (+ ~addend 1)) ~@body)) > > > > => (test-it 3 (println foo)) > > 4 > > nil > > > > => (macroexpand '(test-it 3 (println foo))) > > (do (def fcms.app/foo (clojure.core/+ 3 1)) (println foo)) > > > > => (ns test) > > nil > > test=> (fcms.app/test-it 3 (println foo)) > > CompilerException java.lang.RuntimeException: Can't create defs outside > of > > current ns, compiling:(NO_SOURCE_PATH:1:1) > > > > > > I don't think my scenario is too unusual, but so far I haven't been able > to > > find anything about how to best do this. > > > > It case it helps, the real macro is with-collection and it takes a > > collection name, does a lookup and some validation in a DB, then needs to > > share the collection's id with the body. > > > > Cheers, > > Sean > > > > > > > > -- > > -- > > 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 unsubscribe from this group and stop receiving emails from it, send an > > email to clojure+unsubscr...@googlegroups.com. > > For more options, visit https://groups.google.com/groups/opt_out. > > > > > > > > -- > Baishampayan Ghose > b.ghose at gmail.com > > -- > -- > 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 unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/groups/opt_out. > > > -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.