Last active
September 30, 2020 06:34
-
-
Save rocketnia/cb83da2cfcddbf614dfe1dfc5e08792c to your computer and use it in GitHub Desktop.
Hygiene for a curried macro: A failing test that a Racket macro (M1) generated by a macro (M2) can bind a variable passed to M1.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lang racket | |
(require rackunit) | |
; Hygiene for a curried macro | |
; 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. | |
(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" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment