At Tue, 10 Jul 2012 10:51:57 -0400, Eli Barzilay wrote: > 20 minutes ago, Marijn wrote: > > > > It seems to me that both these results cannot be correct > > simultaneously, but I'll await the experts' opinion on that. > > This does look weird: > > #lang racket > (define-for-syntax (f stx) #`(let ([x 1]) #,stx)) > (define-syntax (m stx) > (with-syntax ([zz (f #'x)]) #`(let ([x 2]) zz))) > (m) > > evaluates to 1, but if I change the first two "stx" names into "x" > *or* if I change the argument name for the macro to "x", then it > returns 2.
It's natural --- but not correct --- to think that #` is responsible for hygiene, in which case `(f #'x)' should keep the given `x' separate from the `let'-bound `x' in the result. Instead, hygiene is the responsibility of macro invocation, and #`(let ([x 1]) #,#'x) is simply the same as #`(let ([x 1]) x) and so (f #'x) above is equivalent to #`(let ([x 1]) x) If you change the example to #lang racket (begin-for-syntax (define-syntax-rule (f body) #`(let ([x 1]) body))) (define-syntax (m stx) (with-syntax ([zz (f x)]) #`(let ([x 2]) zz))) (m) so that `f' is used as a macro instead of a function, then you get 2, since the macro-expansion of `(f x)' keeps the `x's separate. _________________________ Racket Developers list: http://lists.racket-lang.org/dev