Apologies to mobile users. The superscripts added by +scopes aren't boxes
in the Web client.

To clarify my question: how do I handle the situation where variables bound
by one macro and used by another are out of scope when file boundaries are
involved?

The +scopes into shows that the scope sets go from intersecting to disjoint
or sharing only a macro scope.

On Mon, Jun 3, 2019, 11:52 AM Eric Griffis <ded...@gmail.com> wrote:

> Several times now, I've run into one or another form of the following
> problem:
>
> Say I want to build primitives to
>
>    1. declare an "interface" as a list of names, and
>    2. implement and use those names at run time in a limited scope
>
> Concretely, I want to run the following code:
>
> (interface Speaker say speak)
> (implement Speaker displayln (say 'hello) speak)
>
> If I put these lines at the end of a file that implements the two forms,
> it should (displayln 'hello) when I run it.
>
> Here is the interface macro:
>
> (define-syntax (interface stx)
>   (syntax-case stx ()
>     [(_ id member-id ...) #'(define-syntax id #'(member-id ...))]))
>
> The implement macro is trickier. A naive implementation looks like this:
>
> (define-syntax (implement stx)
>   (syntax-case stx ()
>     [(_ class-id def ... expr)
>      (with-syntax ([(id ...) (syntax-e (syntax-local-value #'class-id))])
>        #'(letrec ([id def] ...) expr))]))
>
> It fails with the following message:
>
> ; /tmp/j.rkt:44:30: say: unbound identifier;   in: say;   context...:;    
> #(570423 use-site) [common scopes];   other binding...:;    local;    
> #(570422 macro) [common scopes];   common scopes...:;    #(570223 module) 
> #(570226 module j) #(570426 local) #(570427 intdef);    #(570428 local)
>
> Incorporating the debug-scopes package's +scopes macro shows this:
>
> (letrec⁰˙˙¹
>  ((say⁰˙˙¹ displayln⁰˙˙³) (speak⁰˙˙¹ (say⁰˙˙³ (quote⁰˙˙³ hello⁰˙˙³))))
>  speak⁰˙˙³)ˢˡⁱ⁼²⁺ᵘˢᵉ⁼³0 module   5705121 module j 5705152 macro    5707193 
> use-site 570720
>
> For reasons I don't yet fully comprehend, it just works out if I use
> syntax-local-introduce on the id's, so +scopes gives me this:
>
> (letrec⁰˙˙¹
>  ((say⁰˙˙³ displayln⁰˙˙³) (speak⁰˙˙³ (say⁰˙˙³ (quote⁰˙˙³ hello⁰˙˙³))))
>  speak⁰˙˙³)ˢˡⁱ⁼²⁺ᵘˢᵉ⁼³0 module   5712471 module j 5712502 macro    5714553 
> use-site 571456
>
> But if the interface and implement invocations are not in the same file
> as their implementations, it breaks with a similar error:
>
> ; /tmp/h.rkt:5:30: say: unbound identifier;   in: say;   context...:;    
> #(572682 module) [common scopes];   other binding...:;    local;    #(572388 
> module) #(572391 module j) #(572596 module);    #(572599 module j) [common 
> scopes];   common scopes...:;    #(572685 module h) #(572700 local) #(572701 
> intdef) #(572702 local)
>
> In this situation, +scopes gives:
>
> (letrec⁰˙˙³
>  ((say⁴˙˙⁵ displayln⁴˙˙⁶) (speak⁴˙˙⁵ (say⁴˙˙⁶ (quote⁴˙˙⁶ hello⁴˙˙⁶))))
>  speak⁴˙˙⁶)ˢˡⁱ⁼⁶⁺ᵘˢᵉ⁼0 module   5768541 module j 5768572 module   5770563 
> module j 5770594 module   5771505 module h 5771536 macro    577173
>
> If I move the interface invocation back into the original file and keep
> the implement invocation in a separate file, I get the same error but
> +scopes gives something slightly different:
>
> (letrec⁰˙˙³
>  ((say⁰˙˙⁴ displayln⁴˙˙⁶) (speak⁰˙˙⁴ (say⁴˙˙⁶ (quote⁴˙˙⁶ hello⁴˙˙⁶))))
>  speak⁴˙˙⁶)ˢˡⁱ⁼⁴⁺ᵘˢᵉ⁼0 module   5723881 module j 5723912 module   5725963 
> module j 5725994 macro    5726975 module   5726826 module h 572685
>
> What's going on here? How do I fix this?
>
> Eric
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAORuSUzCs5SiisiLjG3uQMiBdK%2BOHOjq8sgEsNdw54LUMAeEEA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to