On Wed, Jul 27, 2011 at 3:23 PM, Alan Malloy <a...@malloys.org> wrote: > On Jul 27, 11:56 am, Dmitry Gutov <raa...@gmail.com> wrote: >> > First: Why doesn't macroexpand expand the inner when-lets? >> >> It's not supposed to, see the doc. To do full expansion, you can use >> `clojure.walk/macroexpand-all`. >> >> > Is the gensym in the two expands the same thing, or do "they" get the >> > same name? That was surprising to me. I can't think of any real >> > example where that is a problem. But what if I had wanted to write a >> > macro like the second when-lets? >> >> Looks like a bug/limitation of the gensym reader macro, these symbols >> are treated as belonging to the same quoted form, so they get the same >> name. > > Nothing to do with being the same quoted form: foo# symbols are > gensymmed at read time, so by the time the macro runs there's no > evidence that they were ever gensyms: just a symbol named > temp__1551__auto__, and it has no reason to suppose you intend them to > be different.
I'd say it's a bug. This sort of capture/shadowing simply should not happen in Clojure macros without the user jumping through hoops to specifically enable it (e.g. ~'foo; ~(symbol ...)). If the reader is turning the foo#s in a particular syntax-quoted expression into a fixed symbol, I say it should instead be turning `(... foo# ... foo# ...) into an implicit (let [foo (gensym)] `(... ~foo ... ~foo ...)), which the compiler will then turn into code that generates a separate gensym for each invocation of the containing macro, as seems desirable and necessary to avoid the sort of problem observed in this thread. Of course, the implicit let binding needs to be something that won't collide with anything else around, but using the pre-# part of the symbol, as with foo above, ought to suffice for that. When was the last time you saw anyone combine foo# and ~foo, meaning different things, in the same syntax quote? Or use foo# itself as the symbol name. As I understand it, once past the reader layer that's as valid an identifier as any, but one the reader will barf on in any other context. Or, for added meta fun, use (gensym 'foo) to generate it. :) -- Protege: What is this seething mass of parentheses?! Master: Your father's Lisp REPL. This is the language of a true hacker. Not as clumsy or random as C++; a language for a more civilized age. -- 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