[racket] define-syntax vs let-syntax
On 11/16/2010 12:45 PM, Jon Rafkind wrote:
> `define-syntax' has different behavior from `let-syntax' when the
> transformer operates on top-level bindings in the transformer environment.
>
> (define-for-syntax foo 1)
>
> (define-syntax (x1 stx)
> (printf "z: foo is ~a\n" foo)
> (set! foo (add1 foo))
> (printf "z: foo is ~a\n" foo)
> #'1)
>
> (x1)
>
> #;
> (let-syntax ([x1 (lambda (stx)
> (printf "z: foo is ~a\n" foo)
> (set! foo (add1 foo))
> (printf "z: foo is ~a\n" foo)
> #'1)])
> (x1))
>
> With `define-syntax' I see
> z: foo is 1
> z: foo is 2
>
> But with `let-syntax' I see
> z: foo is 1
> z: foo is 1
>
> Is this a bug or am I missing something?
I guess it has to do with expansion order somehow. If I try to
interleave calls to a macro defined by `define-syntax' and the
`let-syntax' expression I see the `define-syntax' expansions happen first.
(define-for-syntax foo 1)
(define-syntax (x2 stx)
(printf "z: foo is ~a\n" foo)
(set! foo (add1 foo))
(printf "z: foo is ~a\n" foo)
#'1)
(x2)
(let-syntax ([x1 (lambda (stx)
(printf "let z: foo is ~a\n" foo)
(set! foo (add1 foo))
(printf "let z: foo is ~a\n" foo)
#'1)])
(x1))
(x2)
z: foo is 1
z: foo is 2
z: foo is 2
z: foo is 3
let z: foo is 3
let z: foo is 3