[racket] Bindings' differences between 5.2.1 and 5.3

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Fri Aug 10 17:53:01 EDT 2012

Yes, this difference in the way that v5.3 and v5.2.1 handle binding was
intended, though it was explained well in the change log.

Your code includes


where the value of `me-name' is a symbol. In both v5.2.1 and v5.3, as
`me-name' is coerced to an identifier (i.e., a syntax object), it gets
its lexical context from the enclosing environment, which is the
"auto-req-lang.rkt" module.

When you inject the identifier into the macro-expansion result as a
`require' path, the `require'd identifiers should only bind identifiers
that have the same context --- that is, other identifiers whose context
is "auto-req-lang.rkt". That's what happens in v5.3, at least. The
identifiers in "example.rkt" don't have that context, and so they don't
get bound.

Identifiers in "example.rkt" did get bound by the `require' in v5.2.1,
because the macro system didn't correctly track module-level context.
It turns out that some natural uses of submodules exposed this
bug/weakness of the macro expander, and so we fixed it. I'm sorry for
the subtle backward incompatibility, though.

Instead of

 (syntax-local-introduce #`#,me-name)

I think you probably want

 (datum->syntax stx me-name)

which should work the same in v5.2.1 and v5.3.

At Wed, 8 Aug 2012 17:32:52 -0300, Gustavo Massaccesi wrote:
> Hi!
> I'm upgrading from version 5.2.1 to version 5.3 and I found a problem.
> The idea is that the module "auto-req-lang.rkt" is like racket/base,
> but when it is used as a language, it is automatically required
> for-syntax. (The name is extracted automatically.) The original file
> is much longer, but this is a minimal example that shows the
> difference between the Racket versions.
> In this case, the following "example.rkt" program works in 5.2.1 but
> fails in 5.3
> ; version 5.2.1 ==> #f
> ; version 5.3   ==> Error: syntax: unbound identifier in the
> transformer environment;
>  also, no #%app syntax transformer is bound in: syntax
> Gustavo
> ;=== file:  "auto-req-lang.rkt"
> #lang racket/base
> (require (for-syntax racket/base))
> (provide (except-out (all-from-out racket/base) #%module-begin))
> (provide (rename-out (module-begin #%module-begin)))
> {define-syntax (module-begin stx)
>   (syntax-case stx ()
>     [(module-begin body ...)
>      (let-values ([(me-name ??) (module-path-index-split (car
> (identifier-binding #'module-begin)))])
>        (with-syntax ([module-id (syntax-local-introduce #`#,me-name)])
>          #`(#%plain-module-begin
>             (require (for-syntax module-id))
>             body ...
>             )))])}
> ;=== end file:  "auto-req-lang.rkt"
> ;=== file:  "example.rkt"
> #lang s-exp "auto-req-lang.rkt"
> {define-syntax (just#f stx)
>   (syntax #f)}
> (display (just#f))
> ;=== file:  "example.rkt"
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Posted on the users mailing list.