[plt-scheme] local special syntax confusion
Psy-Kosh wrote:
> A bit confused about locally redefining special syntax like #%app
>
> What I mean is this:
>
> (let-syntax ((#%app
> (syntax-rules ()
> ((_ a b) (+ a b)))))
> (3 5))
>
> Produces 8 no problem.
>
> on the other hand,
>
> (define-syntax (blah stx)
> (syntax-case stx ()
> ((_ exp)
> (with-syntax
> ((#%app (datum->syntax-object #'exp '#%app)))
> #'(let-syntax ((#%app
> (syntax-rules ()
> ((_ a b) (+ a b)))))
> exp)))))
>
> (blah (3 5))
>
> produces the error "compile: identifier used out of context in: #%app"
> *blinks* huh?
Look at the application '(+ a b)' in the inner 'syntax-rules' template.
The meaning of an application is determined by the nearest binding of
'#%app' [1]. The application isn't in the scope of the nonhygienically
introduced binding, because it's in the right-hand side of 'let-syntax'.
The closest binding is the '#%app' bound using 'with-syntax'. But that
binding disappears when the macro transformer returns; thus the "out of
context" error.
You can usually catch "identifier used out of context" errors by looking
at the local bindings within a macro and checking that they don't appear
in any syntax expressions, like this:
(define-syntax (m stx)
(syntax-case stx ()
[(m ___)
(___ (let ([x ___])
#'(___ x ___)))]))
In this case, the reference to '#%app' is implicit. And if it were
explicit, it would be substituted away as a pattern variable. So it's an
unusual case. My advice would be not to use the implicit syntax names
(like '#%app', '#%datum', '#%top') as pattern variable names.
Ryan
[1] The closest binding with the right lexical context, rather.
> On the other other hand,
>
> (define-syntax (blah stx)
> (syntax-case stx ()
> ((_ exp)
> (with-syntax
> ((app (datum->syntax-object #'exp '#%app)))
> #'(let-syntax ((app
> (syntax-rules ()
> ((_ a b) (+ a b)))))
> exp)))))
>
> (blah (3 5))
>
> produces 8 again.
>
> I'm probably missing something really basic and obvious here, but no
> clue what. So why does #2 fail while both #1 and #3 work?
>
> Thanks
>
> Psy-Kosh
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme