[racket] syntax-parse #:at

From: Jon Rafkind (rafkind at cs.utah.edu)
Date: Tue May 22 02:07:06 EDT 2012

I think my confusion stems from the fact that the inner syntax-parse rebinds 'name' but the original source location is preserved so when I print out #'name in the 'make-transformer' macro I see that it still points at the original 'x'. When I print 'new-name' instead I see it has a source location from the inner syntax-parse expression. I was trying to correlate the source location with the lexical context but that doesn't work. Maybe its a bad idea to use the source location to try to infer lexical properties but source location is the only thing printed with printf -- this is why I don't think printf is a good tool to debug macros.

On 05/21/2012 08:04 PM, Matthew Flatt wrote:
> I don't understand your objections to the `printf' results, but I think
> I can now better explain your original problem.
>
> When the template has
>
>    (syntax-parse stx
>     [(_ new-name)
>      (with-syntax ([output (make-transformer name pattern template)])
>        #'(define-syntax new-name output))])
>
> then the expansion of
>
>   (define-new-syntax x ... ...)
>
> has 
>
>    (syntax-parse stx
>     [(_ new-name)
>      (with-syntax ([output (make-transformer x pattern template)])
>        #'(define-syntax new-name output))])
>
> There's an `x' as the fist sub-form to `make-transformer', as intended.
>
>
> When the `new-name's are changed to `name' so that the template has
>
>    (syntax-parse stx
>     [(_ name)
>      (with-syntax ([output (make-transformer name pattern template)])
>        #'(define-syntax name output))])
>
> then the expansion of
>
>   (define-new-syntax x ... ...)
>
> has 
>
>    (syntax-parse stx
>     [(_ x)
>      (with-syntax ([output (make-transformer x pattern template)])
>        #'(define-syntax x output))])
>
> Again, `x' appears in as the first sub-form of `make-transformer' ---
> but this `x' is bound as a pattern variable by the enclosing
> `syntax-parse', which makes it a different `x' than the one when
> `new-name' is used in the initial template.
>
> At Mon, 21 May 2012 11:10:59 -0600, Jon Rafkind wrote:
>> On 05/21/2012 10:06 AM, Jon Rafkind wrote:
>>> On 05/21/2012 06:02 AM, Matthew Flatt wrote:
>>>> At Sun, 20 May 2012 22:42:30 -0600, Jon Rafkind wrote:
>>>>> The issue is why do I have to use a name other than 'name' for the
>>>>> pattern variable on the line where it says 'HERE'. If I use the
>>>>> 'name' pattern variable then the syntax-parse form generated by
>>>>> 'make-transformer' will use the wrong lexical context for the literal
>>>>> set. I don't see how the lexical context of the outer 'name' differs
>>>>> from the inner 'new-name', other than the 'new-name' has an extra
>>>>> mark on it.
>>>> When you use `name' instead of `new-name', then `name' gets replaced by
>>>> `x' from the use of `define-new-syntax', and `x' (unlike `name') has a
>>>> different lexical context than `new-name'.
>>>>
>>> I thought that too but while debugging it didn't seem to be the case. If I put a 
>> printf in the 'make-transformer' macro to "see" what name is being passed in then 
>> using 'name' or 'new-name' as the pattern variable results in the same thing being 
>> printed.
>>>   (begin-for-syntax
>>>     (define-syntax (make-transformer stx)
>>>       (syntax-parse stx
>>>         [(_ name pattern template)
>>>          (printf "Name is ~a\n" #'name)
>>>          #'#'(lambda (stx)
>>>              (syntax-parse stx
>>>                #:literal-sets ([literals #:at name])
>>>                [pattern template]))])))
>>>
>>>
>>> Then calling 'make-transformer' 3 different ways:
>>>
>>> (lambda (stx)
>>>   (syntax-parse stx
>>>    [(_ new-name)
>>>     (with-syntax ([output (make-transformer name pattern template)])
>>>       #'(define-syntax new-name output))]
>>>
>>> "Name is #<syntax:x.rkt:56:19 x>", where line 56 is the use-site of 
>> 'define-new-syntax'
>>> (lambda (stx)
>>>   (syntax-parse stx
>>>    [(_ name)
>>>     (with-syntax ([output (make-transformer name pattern template)])
>>>       #'(define-syntax name output))]
>>> "Name is #<syntax:x.rkt:56:19 x>"
>>
>> I guess this case doesn't print #<syntax:x.rkt:39 x> because the 'name' at the 
>> use-site of 'make-transformer' is not bound by the pattern variable 'name'. If that 
>> is the case then it seems this case should be identical to the 1st case where it 
>> uses a different pattern variable, 'new-name'.
>> ____________________
>>   Racket Users list:
>>   http://lists.racket-lang.org/users


Posted on the users mailing list.