On 07/10/2012 05:03 PM, Matthew Flatt wrote: > 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)
IIUC then you're saying that also all the following (fx #'x) and (fy #'x) are equivalent to #`(let ((x 0)) x), but if you run this code then you will get a 0 result only for (myy), contrary to what I would expect based on the above explanation. #lang racket (define-for-syntax (fx x) #`(let ((x 0)) #,x)) (define-for-syntax (fy y) #`(let ((x 0)) #,y)) (define-syntax (mxx x) (syntax-case x () ((_) #`(let ((x 99)) #,(fx #'x))))) (define-syntax (mxy x) (syntax-case x () ((_) #`(let ((x 99)) #,(fy #'x))))) (define-syntax (myx y) (syntax-case y () ((_) #`(let ((x 99)) #,(fx #'x))))) (define-syntax (myy y) (syntax-case y () ((_) #`(let ((x 99)) #,(fy #'x))))) (mxx) (mxy) (myx) (myy) ==> 99 99 99 0 Marijn