> I am unable to come up with a program where this difference is significant though
Here's an example: (define-syntax-rule (m) 'old) (let () ($list (m)) (define-syntax-rule (m) 'new)) > So I am curious why internal-definition-context-track is needed. A similar example shows the need here: ($list (define-syntax-rule (m) 5) (m)) Without `internal-definition-context-track` you'll miss the arrow for `m`. While `m` does indeed get rebound in the `letrec-syntaxes+values`, that binding has an extra scope, so the reference to `m` (recorded in an `'origin` property on `5`) doesn't match. On Sunday, June 7, 2020 at 12:18:26 AM UTC-6, Sorawee Porncharoenwase wrote: > > Thank you so much, Michael! This is very helpful. > > I can see that when this form is used within another internal definition > context, then my version and your version will expand in different order, > and I agree that yours makes more sense. I am unable to come up with a > program where this difference is significant though (e.g., one fails while > the other doesn’t). “so that names bound by later definitions are > available” seems to suggest that things like this is not supposed to work > on my version: > > (let () > ($list (define (f x) (g x)) > (println f)) > (define (g x) x) > (void)) > > but it actually does… > > I also have another question. When should I use > internal-definition-context-track? Normally, internal definitions are > expanded into letrec-syntaxes+values, so the bindings don’t actually > disappear. So I am curious why internal-definition-context-track is > needed. > > Thanks again. > > On Sat, Jun 6, 2020 at 8:21 AM Michael Ballantyne <[email protected] > <javascript:>> wrote: > >> 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 <the-original-call>)`. 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 < >>> [email protected]> 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 [email protected] <javascript:>. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/racket-users/748eead8-76b9-43bc-94da-2c832ba8896do%40googlegroups.com >> >> <https://groups.google.com/d/msgid/racket-users/748eead8-76b9-43bc-94da-2c832ba8896do%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/ae981bda-94d3-43d2-ae23-a41f5160aa0ao%40googlegroups.com.

