[racket] Confusion with syntax marks

From: Eric Dobson (eric.n.dobson at gmail.com)
Date: Sat Oct 8 16:11:27 EDT 2011

Thanks. That is what I eventually figured out I needed to do. Also the original problem was a bug in the Macro Stepper, pr12248, which only added to my confusion.

-Eric

On Oct 8, 2011, at 12:18 PM, Marco Maggi wrote:

> Eric Dobson wrote:
> 
>> I am playing  around with syntax marks and  have a program
>> whose output confuses me.
>> 
>> #lang racket
>> (require (for-syntax racket/syntax))
>> (define-for-syntax marker (make-syntax-introducer))
>> (define-syntax (mark stx)
>>  (syntax-case stx ()
>>    ((_ arg ...) (marker #'(begin arg ...)))))
>> 
>> (define foo 'a)
>> (mark
>> (define foo 'b)
>> foo
>> (mark foo))
>> foo
>> (mark foo)
>> (mark (mark foo))
>> 
>> This  outputs 5 values  depending on  which foo  a binding
>> refers to.  Racket outputs 'b 'b  'a 'a 'a. But when I use
>> the macro stepper  and look at the marks  on the uses line
>> up with the bindings they  alternate 'b 'a 'a 'b 'a, which
>> is what I  was expecting, but the arrows  line up with the
>> output.  Can  someone  explain  why  I  am  getting  these
>> results?
> 
> No answers  so... I know  nothing of Racket's  internals and
> the macro stepper, but I guess the "problem" is: you are not
> using the  marks the way they  are meant to  be and Racket's
> "same marks" predicate does not do what you expect.
> 
>  Does the following program do what you expect?
> 
> #lang racket
> (require (for-syntax racket/syntax))
> 
> (define (print x)
>  (display x)
>  (newline))
> 
> (define-for-syntax marker (make-syntax-introducer))
> 
> #;(define-syntax (mark stx)
>  (syntax-case stx ()
>    ((_ arg ...)
>     (marker #'(begin arg ...)))))
> 
> (define-syntax (mark stx)
>  (syntax-case stx ()
>    ((_ arg ...)
>     (syntax-local-introduce
>       (marker
>         (syntax-local-introduce #'(begin arg ...)))))))
> 
> (define foo 'a)
> (mark
> (define foo 'b)
> (print foo)
> (print (mark foo)))
> (print foo)
> (print (mark foo))
> (print (mark (mark foo)))
> 
>  When Racket defines a mark, it uses that mark value itself
> as its antimark; this is different from what other expanders
> do  (for  example: psyntax  uses  #f  as universal  antimark
> capable of annihilating every mark).
> 
>  The STX  syntax object handed  to the MARK  transformer is
> marked by the  expander pushing on its marks  stack a mark W
> specific for such  transformer; SYNTAX-CASE duplicates STX's
> marks stack  into ARG, then pushes  W on the  marks stack of
> ARG;  when  the  transformer  returns, the  returned  syntax
> object is marked  again by the expander with  W.  The MARKER
> function marks its argument with the mark M.
> 
>  To do  what you want to  do: first you  have to annihilate
> the W  added to  ARG with the  inner SYNTAX-LOCAL-INTRODUCE,
> then  you add M  using MARKER,  finally you  add W  with the
> outer SYNTAX-LOCAL-INTRODUCE; this  last W is annihilated by
> the W added by the expander to the output syntax object.
> 
>  Summary of marks pushed into ARG:
> 
>                   annihilated
>                       | |
> ... previous marks ... W W M W W
>                             | |
>                          annihilated
> 
> and  the final  result is  that ARG  in the  output  form is
> marked with:
> 
> ... previous marks ... M
> 
> HTH
> -- 
> Marco Maggi
> _________________________________________________
>  For list-related administrative tasks:
>  http://lists.racket-lang.org/listinfo/users




Posted on the users mailing list.