[plt-scheme] syntax identifier used out of context

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Thu Dec 11 14:59:37 EST 2008

You could move `bar2' out of `foo' using `define-for-syntax',

 (define-for-syntax (bar2 stx3)
   (syntax-case stx3 ()
     ((_ q) #'(+ 1 q))))

and then it works to replace the lambda with `bar2', as you expected.

You could also leave the lambda so that the expansion of `x' refers to
`bar2', in which base `bar2' needs to be a macro, but still outside of

 (define-syntax (bar2 stx3)
   (syntax-case stx3 ()
     ((_ q) #'(+ 1 q))))

 (define-sytax (foo stx)
   (syntax-case stx ....))

If you keep the `bar2' definition inside of `foo' and if `foo' returns
a syntax object that refers to `bar2', then you get an out-of-context
error. That's because a syntax object captures binding information, but
not values; the macro expander knows that `bar2' was lexically bound,
but the dynamic invocation of the `foo' transformer has already
returned at the point for expanding `bar2', so there's no value for the
binding in the compile-time environment.

At Thu, 11 Dec 2008 00:21:49 -0700, Jon Rafkind wrote:
> I'm wondering why I get this error from the following code. I was 
> helping someone on IRC so I don't have a real use case, just wondering 
> what the error means. If I change bar2 to bar in the template then it 
> works. Also it seems like I should be able to replace the lambda in 
> syntax-parameterize by just bar2, but then I get an error about bar2 not 
> being bound in the transformer environment.
>  > compile: identifier used out of context in: bar2
> #lang scheme
> (require scheme/stxparam)
> (define-syntax-parameter x (lambda (stx) (error "dont use x")))
> (define-syntax bar
>   (syntax-rules ()
>     ((_ q) (+ 1 q))))
> (define-syntax (foo stx)
>   (define (bar2 stx3)
>     (syntax-case stx3 ()
>       ((_ q) #'(+ 1 q))))
>   (syntax-case stx ()
>     ((_ pat) #'(syntax-parameterize ([x (lambda (stx3)
>                                           (syntax-case stx3 ()
>                                              ((_ . q) #'(bar2 . q)))) ])
>                    (begin
>                      (printf "You won ~a!\n" pat))))))
> (foo (x 4))
> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme

Posted on the users mailing list.