[plt-scheme] macro-generating macros and the bizarre properties of syntax-local-get-shadower

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Mon May 14 18:24:08 EDT 2007

`syntax-local-get-shadower' is indeed bizarre, and I regret having
exposed it in MzScheme. The only good use for it that I know is to
implement `syntax-parameterize'.

As for the problem with `define-foo1', here's a simpler version of the
same problem:

 (define-syntax (define-x stx)
   (syntax-case stx ()
     [(_ id v) 
      (with-syntax ([(g) (generate-temporaries '(g))])
        #'(define-syntax (id stx)
            (let ([g v])
              #`#,g)))]))
 (define-x foo 4)
 foo

It boils down to this: what lexical context is given to a datum that is
converted to a syntax object by `quasisyntax' via an `unsyntax'? The
answer is that it's the context of the expression under `unsyntax'.

That is, in the even simpler example

   (let ([x 2]) 
     #`#,x)

the new syntax object for 2 is given the lexical context of the `x'
use.

In the `define-x' example above, the syntax form of 4 is given the
lexical context of the `g' use. But `g' is generated by
`generate-temporaries', which means that it starts out with an empty
lexical context, so that it includes no binding for `#%datum'.

Jens Axel solved the problem by converting the number to a syntax
object explicitly, instead of letting `quasisyntax' pick a context.

It's possible that a better choice would be the lexical context of the
`unsyntax', instead of the expression under the `unsyntax. That would
have automagically given you the result you want in this case. I think
the current choice of context is probably the right one, though,
because it works better when the expression under `unsyntax' was itself
part of a macro input.

Matthew



Posted on the users mailing list.