I tried
```
(define-syntax my-file
  (make-require-transformer
   (lambda (stx)
     (syntax-case stx ()
       [(_ path)
        (printf "Importing: ~a~n" #'path)
        (expand-import #'(file path))]))))
(require (my-file "test.rkt"))
```
with the same result: no errors in require, but no imports.

So, it seems, that the only solution is datum->syntax. It works fine.

понедельник, 13 июля 2020 г., 10:17:26 UTC+5 пользователь Michael MacLeod 
написал:
>
> 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 <[email protected] 
> <javascript:>> 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 [email protected] <javascript:>.
>> 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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/e59254cd-7044-4bb1-a0de-75957c1558fao%40googlegroups.com.

Reply via email to