I'll also put in a plug for DrRacket's Macro Stepper, which can show your
scopes in pretty colors! (And precise numbers.) In particular, in the
"Stepper > Foreground colors" menu, you can toggle between "By macro
scopes" and "By all scopes".

[image: Screen Shot 2020-09-30 at 3.47.40 AM.png]
-Philip


On Wed, Sep 30, 2020 at 3:40 AM Philip McGrath <phi...@philipmcgrath.com>
wrote:

> Hi Nia,
>
> Here's a variant that passes your test:
>
> #lang racket
>
> (require rackunit
>          syntax/parse/define)
>
> (define-syntax let-second-and-create-let-third
>   (syntax-parser
>     [(_ var let-third body-of-let-second)
>      #'(let ([var "second"])
>          (let-syntax ([let-third
>                        (syntax-parser
>                          [(_ body-of-let-third)
>                           #:with var* (syntax-local-introduce #'var)
>                           #'(let ([var* "third"])
>                               body-of-let-third)])])
>            body-of-let-second))]))
>
> (check-equal?
>   (let ([x "first"])
>     (let-second-and-create-let-third x let-third
>       (let-third
>         x)))
>   "third"
>   "Test that a macro generated by a macro can bind a variable the user
> supplied to the generator macro")
>
> You need `syntax-local-introduce` (or another mechanism, like
> `datum->syntax`) for `let-third` to be able to capture `x` in its body:
> otherwise, the expander will see that it is a macro-introduced binding. You
> also need to address the fact that each `let` in the expansion creates a
> new scope: if the binding to `"second"` isn't in scope for the
> right-hand-side of `let-third`, you can get an ambiguous binding (see:
> https://www.cs.utah.edu/plt/scope-sets/pattern-macros.html#(part._pattern-ambiguous)).
> In this case I just moved the `let-syntax` inside the `let`, but you could
> also use something like `letrec-syntaxes+values`.
>
> -Philip
>
> On Wed, Sep 30, 2020 at 2:46 AM rocketnia <roki...@gmail.com> wrote:
>
>>
>> Hi all,
>>
>> I've been experimenting with a custom system of managed local variables,
>> and I came up with a hygiene test case that was failing. So then I tried
>> the same test case with plain Racket variables, and it failed that way
>> too. Here's a minimalistic example.
>>
>> Basically, this is a curried macro: The user supplies a variable and gets
>> a macro out, and then the user calls that macro. Can the second macro
>> bind the variable the user supplied to the first one? I thought it would
>> be able to, but this doesn't currently seem to be case on Racket v7.8
>> [cs].
>>
>> Could anyone explain what's going on with this? Is there a workaround if
>> I want to write this kind of macro? Should I file a bug in Racket? This
>> looks pretty close to R5RS Scheme, so I wonder what the situation in the
>> broader Scheme world is like, too.
>>
>>
>> #lang racket
>>
>> (require rackunit)
>>
>> (define-syntax-rule
>>   (let-second-and-create-let-third var let-third body-of-let-second)
>>   (let-syntax ([let-third
>>                  (syntax-rules ()
>>                    [(let-third body-of-let-third)
>>                     (let ([var "third"])
>>                       body-of-let-third)])])
>>     ; This binding shows that the first macro *does* manage to bind
>>     ; the given variable, even though the second macro doesn't.
>>     (let ([var "second"])
>>       body-of-let-second)))
>>
>> (check-equal?
>>   (let ([x "first"])
>>     (let-second-and-create-let-third x let-third
>>       (let-third
>>         x)))
>>   "third"
>>   "Test that a macro generated by a macro can bind a variable the user
>> supplied to the generator macro")
>>
>> ; FAILURE
>> ; actual: "second"
>> ; expected: "third"
>>
>>
>> You can also find this code in Gist form here:
>> https://gist.github.com/rocketnia/cb83da2cfcddbf614dfe1dfc5e08792c
>>
>> Thanks in advance for any insight you have about what's going on here.
>>
>> - Nia
>>
>> --
>> 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/71daa8da-25cf-426b-b709-ee9ed25b53f0n%40googlegroups.com
>> <https://groups.google.com/d/msgid/racket-users/71daa8da-25cf-426b-b709-ee9ed25b53f0n%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
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/01000174ddff1f9f-f60fe46f-efc2-40c6-bac5-f9f5a2926f8a-000000%40email.amazonses.com.

Reply via email to