[racket-users] Re: identifier used out of context

2020-06-06 Thread Michael Ballantyne
Explicitly expanding `e` would ensure that the expansion work only has to 
happen once, rather than twice. Even so, the fully-expanded syntax will be 
expanded again in `syntax-local-bind-syntaxes` and in the expansion.

As far as I've seen, the only thing that liberal define contexts control is 
whether definitions of functions that accept keyword arguments expand to a 
normal `define-values` with runtime handling of keywords, or expand to a 
collection of macros and function definitions that allow a more efficient 
calling convention for first-order calls. The latter expansion doesn't work 
for contexts like `class` where function definitions are re-interpreted in 
a way that adds indirection, so it is only enabled in contexts that opt-in.

I see more bug in your macro: as its very first task, it should check if 
`(syntax-local-context)` is `'expression`. If not, it should expand to 
`(#%expression )`. This ensures that its expansion is 
delayed until the second pass of the surrounding definition context so that 
names bound by later definitions are available. 

On Saturday, June 6, 2020 at 4:15:00 AM UTC-6, Sorawee Porncharoenwase 
wrote:
>
> Ah, apparently I need syntax-local-identifier-as-binding. Here’s a 
> revised code that passes the tests.
>
> (begin-for-syntax
>   (define ((do-it gs ctx) e)
> (let loop ([e e])
>   (define e-expanded (local-expand e
>(list gs)
>(list #'begin
>  #'define-syntaxes
>  #'define-values)
>ctx))
>   (syntax-parse e-expanded
> #:literals (begin define-syntaxes define-values)
> [(begin body ...) #`(begin #,@(map loop (attribute body)))]
> [(define-values (x ...) e)
>  #:with (x* ...) (map syntax-local-identifier-as-binding
>   (attribute x))
>  (syntax-local-bind-syntaxes (attribute x) #f ctx)
>  #'(define-values (x* ...) e)]
> [(define-syntaxes (x ...) e)
>  #:with (x* ...) (map syntax-local-identifier-as-binding
>   (attribute x))
>  (syntax-local-bind-syntaxes (attribute x) #'e ctx)
>  #'(define-syntaxes (x* ...) e)]
> [e #'(set! acc (cons e acc))]
>
> Still not sure if there’s still anything wrong. In particular, do I need 
> to expand e in define-syntaxes? And do I need to use 
> prop:liberal-define-context for gs? (I don’t understand what liberal 
> expansion is even after reading the docs several times) Both of these are 
> done in the implementation of block, but without them, it seems to work 
> equally well.
>
> On Fri, Jun 5, 2020 at 6:30 PM Sorawee Porncharoenwase <
> sorawe...@gmail.com > wrote:
>
>> Hi Racketeers,
>>
>> I’m creating a macro that collects values in the internal-definition 
>> context. E.g.,
>>
>> ($list 
>>  1
>>  (define x 2)
>>  x)
>>
>> should evaluate to '(1 2).
>>
>> Here’s my implementation, and it kinda works:
>>
>> #lang racket
>>
>> (begin-for-syntax
>>   (define ((do-it gs ctx) e)
>> (let loop ([e e])
>>   (define e-expanded (local-expand e (list gs) #f ctx))
>>   (syntax-case e-expanded (begin define-syntaxes define-values)
>> [(begin body ...)
>>  #`(begin #,@(map loop (syntax->list #'(body ...]
>> [(define-values ids e)
>>  (begin
>>(syntax-local-bind-syntaxes (syntax->list #'ids) #f ctx)
>>e-expanded)]
>> [(define-syntaxes ids e)
>>  (begin 
>>(syntax-local-bind-syntaxes (syntax->list #'ids) #'e ctx)
>>#'(begin))]
>> [e #'(set! acc (cons e acc))]
>>
>> (define-syntax ($list stx)
>>   (define gs (gensym))
>>   (define ctx (syntax-local-make-definition-context))
>>   (syntax-case stx ()
>> [(_ body ...)
>>  #`(let ([acc '()])
>>  #,@(map (do-it gs ctx) (syntax->list #'(body ...)))
>>  (reverse acc))]))
>>
>> ($list 1
>>(define x 2)
>>x)
>>
>> There are problems though. If I change define to define2 as follows:
>>
>> (define-syntax-rule (define2 x y)
>>   (define-values (x) y))
>>
>> ($list 1
>>(define2 x 2)
>>x)
>>
>> Then I get the “identifier used out of context” error. This doesn’t make 
>> sense to me at all. My define2 should be very similar to define…
>>
>> There’s also another weird problem:
>>
>> ($list 1
>>(define-syntax (x stx) #'2)
>>x)
>>
>> The above works perfectly, but by wrapping x with #%expression, I get 
>> the “identifier used out of context” error again.
>>
>> ($list 1
>>(define-syntax (x stx) #'2)
>>(#%expression x))
>>
>> What did I do wrong?
>>
>> Thanks!
>>
>

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

[racket-users] Re: identifier used out of context

2020-06-06 Thread Sorawee Porncharoenwase
Ah, apparently I need syntax-local-identifier-as-binding. Here’s a revised
code that passes the tests.

(begin-for-syntax
  (define ((do-it gs ctx) e)
(let loop ([e e])
  (define e-expanded (local-expand e
   (list gs)
   (list #'begin
 #'define-syntaxes
 #'define-values)
   ctx))
  (syntax-parse e-expanded
#:literals (begin define-syntaxes define-values)
[(begin body ...) #`(begin #,@(map loop (attribute body)))]
[(define-values (x ...) e)
 #:with (x* ...) (map syntax-local-identifier-as-binding
  (attribute x))
 (syntax-local-bind-syntaxes (attribute x) #f ctx)
 #'(define-values (x* ...) e)]
[(define-syntaxes (x ...) e)
 #:with (x* ...) (map syntax-local-identifier-as-binding
  (attribute x))
 (syntax-local-bind-syntaxes (attribute x) #'e ctx)
 #'(define-syntaxes (x* ...) e)]
[e #'(set! acc (cons e acc))]

Still not sure if there’s still anything wrong. In particular, do I need to
expand e in define-syntaxes? And do I need to use
prop:liberal-define-context for gs? (I don’t understand what liberal
expansion is even after reading the docs several times) Both of these are
done in the implementation of block, but without them, it seems to work
equally well.

On Fri, Jun 5, 2020 at 6:30 PM Sorawee Porncharoenwase <
sorawee.pw...@gmail.com> wrote:

> Hi Racketeers,
>
> I’m creating a macro that collects values in the internal-definition
> context. E.g.,
>
> ($list
>  1
>  (define x 2)
>  x)
>
> should evaluate to '(1 2).
>
> Here’s my implementation, and it kinda works:
>
> #lang racket
>
> (begin-for-syntax
>   (define ((do-it gs ctx) e)
> (let loop ([e e])
>   (define e-expanded (local-expand e (list gs) #f ctx))
>   (syntax-case e-expanded (begin define-syntaxes define-values)
> [(begin body ...)
>  #`(begin #,@(map loop (syntax->list #'(body ...]
> [(define-values ids e)
>  (begin
>(syntax-local-bind-syntaxes (syntax->list #'ids) #f ctx)
>e-expanded)]
> [(define-syntaxes ids e)
>  (begin
>(syntax-local-bind-syntaxes (syntax->list #'ids) #'e ctx)
>#'(begin))]
> [e #'(set! acc (cons e acc))]
>
> (define-syntax ($list stx)
>   (define gs (gensym))
>   (define ctx (syntax-local-make-definition-context))
>   (syntax-case stx ()
> [(_ body ...)
>  #`(let ([acc '()])
>  #,@(map (do-it gs ctx) (syntax->list #'(body ...)))
>  (reverse acc))]))
>
> ($list 1
>(define x 2)
>x)
>
> There are problems though. If I change define to define2 as follows:
>
> (define-syntax-rule (define2 x y)
>   (define-values (x) y))
>
> ($list 1
>(define2 x 2)
>x)
>
> Then I get the “identifier used out of context” error. This doesn’t make
> sense to me at all. My define2 should be very similar to define…
>
> There’s also another weird problem:
>
> ($list 1
>(define-syntax (x stx) #'2)
>x)
>
> The above works perfectly, but by wrapping x with #%expression, I get the
> “identifier used out of context” error again.
>
> ($list 1
>(define-syntax (x stx) #'2)
>(#%expression x))
>
> What did I do wrong?
>
> Thanks!
>

-- 
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/CADcuegtN-s79H1sLV0qo93Dq5uzD3tR6-ZRT1UCLNF7VAqfM0Q%40mail.gmail.com.