The issue isn't actually with the `(_ (x y))` pattern---it's with the `#'(require (x y))` template.
When `require` is passed a module path like `(file "test1.rkt")`, it introduces any identifiers [just `ok` in this case] with the same lexical context of the module path itself[1]. The issue is that the expansion of `req2` adds a macro introduction scope to the `(file "test1.rkt")` syntax object. Since the module path has an additional scope, `ok` will have an additional scope; it won't bind the `ok` from test2.rkt, and we get an unbound identifier error. With `req1`, the parentheses around (file "test1.rkt") in the expanded code come from the use site of the macro, so the `ok` identifier will have the expected lexical context. With `req2`, the parentheses around (file "test1.rkt") in the expanded code come from the macro itself, not from the use site of the macro. Notice the difference: in `(require x)` the parentheses are "in the x", but in #'(require (x y)) the parentheses are from the (#') template. You may be able to achieve your end goal using make-require-transformer[2], which would probably end up being much nicer than what I'm about to go into. Alternatively you could resort to using the unhygenic `datum->syntax` to ensure that the resulting syntax object doesn't have the extra macro introduction scope. I've added some checks before the template to ensure that the forms passed to the macro are of the proper shape. ``` (define-syntax (req2 stx) (syntax-case stx () [(_ (x y)) ; throw a "bad syntax" error if the ; arguments are incorrect (and (free-identifier=? #'x #'file) (string? (syntax-e #'y))) #`(require #,(datum->syntax ; create the syntax object (x y) ; using the lexical context of y #'y (list #'x #'y)))])) ``` You may want to use `syntax-parse` instead, which makes these sorts of checks much simpler to write, and usually gives better error messages than "bad syntax". ``` (require (for-syntax racket/base syntax-parse)) (define-syntax (req2 stx) (syntax-parse stx [(_ ((~literal file) y:str)) #`(require #,(datum->syntax #'y (list #'file #'y)))])) ``` --- [1] `module-path` part under the `require` section from https://docs.racket-lang.org/reference/require.html?q=require#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29 [2] https://docs.racket-lang.org/reference/stxtrans.html?q=require%20transfo#%28def._%28%28lib._racket%2Frequire-transform..rkt%29._make-require-transformer%29%29 On Sun, Jul 12, 2020 at 8:18 PM Roman Klochkov <kalimehta...@gmail.com> wrote: > I try to make a macro, that expands to the require form. > > I put in test1.rkt > ``` > #lang racket/base > (provide ok) > (define ok 1) > ``` > > I put in test.rkt > ``` > #lang racket > (define-syntax (req1 stx) > (syntax-case stx () > [(_ x) #'(require x)])) > > (define-syntax (req2 stx) > (syntax-case stx () > [(_ (x y)) #'(require (x y))])) > > (req2 (file "test1.rkt")) > ok > ``` > > When I run it, I have the error: ok: unbound identifier > > If I change `req2` to `require` or to `req1`, then it returns 1 as should. > > What's wrong with (_ (x y)) pattern ? > > -- > 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/af6dcad0-69ff-406f-8183-dc691d302a5eo%40googlegroups.com > <https://groups.google.com/d/msgid/racket-users/af6dcad0-69ff-406f-8183-dc691d302a5eo%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/CACehHmCq2dsK1gY8W0tVRMBtNpttGD0d2UpK6AmN2PvVMUm6mA%40mail.gmail.com.