# [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.