[racket-dev] Enhancement to the syntax system?

From: Marijn Schouten (hkBst) (hkbst at gentoo.org)
Date: Sat May 3 17:29:21 EDT 2014

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

Posted on the dev mailing list.