[plt-scheme] Compile and Run-Time Phase question

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Wed Jan 21 21:30:03 EST 2009

At Wed, 21 Jan 2009 14:18:11 -0800 (PST), Adrian Patino wrote:
> (define-syntax identifier-syntax
>   (lambda (x)
>     (syntax-case x ()
>       ((_ e)
>        (syntax
>          (lambda (x)
>            (syntax-case x ()
>              (id
>               (identifier? (syntax id))
>               (syntax e))
>              ((id x (... ...))
>               (identifier? (syntax id))
>               (syntax (e x (... ...)))))))))))
> 
> (let ((x 0))
>   (define-syntax x++
>     (identifier-syntax
>       (let ((t x)) (set! x (+ t 1)) t)))
>   (let ((a x++))
>     (list a x)))
> 
> returns with error:
> expand: unbound identifier in module (in the transformer environment,
> which does not include the macro definition that is visible to run-
> time expressions)
> 
> using (define-for-syntax identifier-syntax ...) insteads returns with
> error:
> compile: identifier used out of context in: x
> referring to the x in the let expression.
> 
> Why is it out of context?

When you use `define-for-syntax', then you bind a function
`identifier-syntax' that can be used directly in an transformer
expression. So, `(identifier-syntax (let ((t x)) ...))' is treated as a
function call, and `x' is treated as a direct reference to the one
bound to 0. A transformer expression cannot refer directly to a
run-time variable (since it doesn't exist, yet), so that's why you get
an out-of-context error.


> Also, I noticed that other scheme implementations allow this code to
> work, such as ypsilon. What are the benefits of using define-for-
> syntax?

`define-for-syntax' is not what you want in this case. It binds a
variable at compile time for use at compile time. You want to bind a
macro at compile time for use at compile time. So, you'd want
`define-syntax-for-syntax' --- which isn't currently supported.

To make this code work in PLT Scheme, you have to put
`identifier-syntax' in a separate module, and then import it
`for-syntax' into the module that uses `identifier-syntax' for a
transformer expression.


Matthew



Posted on the users mailing list.