Stephen Compall <stephen.comp...@gmail.com> writes: > On Tue, 2011-12-06 at 16:09 +0100, Tassilo Horn wrote: >> Wikipedia lists syntax-case as hygienic macro system, which would >> make it less powerful than CL macros, because if that was true, you >> could not write anaphoric macros with it. > > You can write anaphora with syntax-case. In fact, defmacro itself can > be defined as a simple syntax-case macro.
Ok, I see. I'm still keen to see a simple syntax-case example demonstrating what you simply cannot do with defmacro. In the mean-time, I've found some post about Racket's macro implementation: http://blog.racket-lang.org/2011/04/writing-syntax-case-macros.html That says the fundamental difference between defmacro and syntax-case macros is that the latter "instead of dealing with plain symbols, you're dealing with these syntax values (called “identifiers” in this case) that are essentially a symbol and some opaque information that represents the lexical scope for its source." Do I see it correctly that the following Common Lisp defmacro is broken because of that missing lexical scope? --8<---------------cut here---------------start------------->8--- * (defun my-plus (&rest xs) (apply #'+ xs)) MY-PLUS * (defmacro foo (&rest xs) `(my-plus ,@xs)) FOO * (foo 1 2) 3 * (labels ((my-plus (&rest xs) (apply #'- xs))) (foo 1 2)) -1 ;; Ouch! my-plus should not shadow macro expansion internals! --8<---------------cut here---------------end--------------->8--- Here, the local function `my-place' captures the global definition of `my-plus'. First, I've thought I could easily get rid of that issue by using my-plus's package qualified name, but I was wrong: --8<---------------cut here---------------start------------->8--- * (defmacro foo (&rest xs) `(common-lisp-user::my-plus ,@xs)) FOO * (labels ((my-plus (&rest xs) (apply #'- xs))) (foo 1 2)) -1 --8<---------------cut here---------------end--------------->8--- Am I doing something wrong, or is there no way to avoid that capture in CL? (Possibly, CL explicitly forbids rebinding standard CL function names for exactly that reason.) That said, in Clojure the example works fine, because everything inside the macro expansion is qualified. --8<---------------cut here---------------start------------->8--- user> (defmacro foo [& exps] `(+ ~@exps)) #'user/foo user> (foo 1 2) 3 user> (let [+ #(apply - %&)] (foo 1 2)) 3 user> (macroexpand '(foo 1 2)) (clojure.core/+ 1 2) --8<---------------cut here---------------end--------------->8--- And the other way round, passing functions into macros, works also fine. For example, here the rebound + shadows clojure.core/+, which is clearly intended. (Of course, this works fine in CL, too). --8<---------------cut here---------------start------------->8--- user> (defmacro bar [x & args] `(~x ~@args)) #'user/bar user> (let [+ #(apply - %&)] (bar + 1 2)) -1 --8<---------------cut here---------------end--------------->8--- Does that mean that Clojure's defmacro is aware of the lexical scope as well and is therefore equally powerful as Scheme's syntax-case? Bye, Tassilo -- 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