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.

Reply via email to