OK, so here are the main points I'm gathering from this discussion. 1. Clojure's quasiquote system does some extra things behind the scenes in terms of generating temporary variables and qualifying variable names with their namespace in such a way that the macros you write are reasonably hygienic. 2. They are not perfectly hygienic because the gensym is simplistic and there may be ways to defeat it if someone tried hard enough. Also, rebinding the global things that the macro depends on may result in unintended behavior. (Then again, you could argue that if you rebind the global "if", you really do want macros like "while" to change.) 3. Clojure does not have macros that are only valid within some local context. All macros are global, and this might result in a lack of expressiveness versus Racket's system. 4. Racket's macro system tracks things like source code location (and possibly other things?) useful for debugging.
Point 3 is the main one I'm still getting my head around. I had to do a little research to understand what everyone was talking about here with "local macros" and "scoped macros". I see now that in Racket, if you define a macro inside some sort of function body (or other lexical scope), it is only valid within that scope. Here are a couple of examples from Clojure to contrast that behavior with: (def x 3) (let [x 2] (defmacro apply-to-x [y] `(~y ~x))) In this code snippet, x is a global, and apply-to-x is a global macro, but the macro does look up x in its local context, i.e., (apply-to-x identity) yields 2, not 3. On the other hand removing the ~ from the x like this: (let [x 2] (defmacro apply-to-x [y] `(~y x))) causes the x in the macro to refer to the global x. So, (apply-to-x identity) yields 3. So it is possible in Clojure to make the macro refer to its local scope, but the macro itself is always global. I recognize that this means there are things you can do in Racket with macros that would be extremely difficult or impossible in Clojure, but I don't have a good sense for how often this would occur in practice. I gather it would be more of an issue for things on a large scale like Racket's class system. _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users