[racket] Bindings' differences between 5.2.1 and 5.3
Thanks! It works.
I'm still trying to be sure that I understand correctly all the
technical details.
When I see the code in the macro-stepper, in both versions the
"auto-req-lang.rkt" is painted with the same color (black). (I suspect
that the macro-stepper is using only the syntax marks, but not the
module context information.)
With this construction, it is also possible to have two identifiers
that look equal in the macro-stepper but they are bounded differently.
I don't have a real word example of this problem, but I constructed
one.
These problems are shown in the following example. In each case the
"-bad" version use my old method, and the "-good" version use your
method. In the macro-stepper all the appearances of
"auto-req-lang.rkt" and "show" are painted in black.
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-good (datum->syntax stx me-name)]
[module-id-bad (syntax-local-introduce
(datum->syntax #'stx me-name))]
[show-good (datum->syntax stx 'show)]
[show-bad (syntax-local-introduce (datum->syntax
#'stx 'show))])
#`(#%plain-module-begin
(require (for-syntax module-id-good))
(require (for-syntax module-id-bad))
(define show-good display)
(define show-bad display)
(show-good "G")
(show-bad "B")
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))
;=== end file: "example.rkt"
On Fri, Aug 10, 2012 at 6:56 PM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
>"was explained well" -> "was not explained well"!
On Fri, Aug 10, 2012 at 6:53 PM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
> 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
>
> #`#,me-name
>
> 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