Re: [racket-users] require and syntax-case

2020-07-14 Thread Michael Ballantyne
> There is another way: syntax-local-introduce will remove the macro scope.

`syntax-local-introduce` is no longer useful for this purpose since the 
switch to the scope sets model. Other scopes, such as module scopes, will 
often distinguish the macro-introduced name. For example, using 
`syntax-local-introduce` won't produce the desired behavior when `req2` is 
defined in one module and used in another.

On Monday, July 13, 2020 at 6:32:58 PM UTC-6, Ben Greenman wrote:
>
> On 7/13/20, Roman Klochkov > wrote: 
> > 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. 
>
> There is another way: syntax-local-introduce will remove the macro scope. 
>
> ``` 
> (define-syntax (req2 stx) 
>   (syntax-case stx () 
> [(_ (x y)) (syntax-local-introduce #'(require (x y)))])) 
> ``` 
>

-- 
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/95494fe6-9a3f-42ac-a5c3-bf8c91c91c69o%40googlegroups.com.


Re: [racket-users] require and syntax-case

2020-07-13 Thread Ben Greenman
On 7/13/20, Roman Klochkov  wrote:
> 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.

There is another way: syntax-local-introduce will remove the macro scope.

```
(define-syntax (req2 stx)
  (syntax-case stx ()
[(_ (x y)) (syntax-local-introduce #'(require (x y)))]))
```

-- 
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/CAFUu9R563Pr8TZkJVBjFYZjf5LcCWfEezdJ1uKjhErp3-zpzAg%40mail.gmail.com.


Re: [racket-users] require and syntax-case

2020-07-13 Thread Roman Klochkov
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  > 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...@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
>>  
>> 
>> .
>>
>

-- 
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/e59254cd-7044-4bb1-a0de-75957c1558fao%40googlegroups.com.


Re: [racket-users] require and syntax-case

2020-07-12 Thread 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 
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
> 
> .
>

-- 
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.


[racket-users] require and syntax-case

2020-07-12 Thread Roman Klochkov
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.