[racket-dev] Enhancement to the syntax system?
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.