Perhaps I missed something, but the error in the first example is because there’s no expression at the end of let. If I use this code instead, it seems to work fine, with the arrow of m pointing to the “new” one.
(define-syntax-rule (m) 'old) (let () (list+ (m)) (define-syntax-rule (m) 'new) (void)) The second example perfectly shows why I need internal-definition-context-track, however. Thank you very much. On Sun, Jun 7, 2020 at 7:51 AM Michael Ballantyne < [email protected]> wrote: > > 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]> >> 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]. >>> 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 > <https://groups.google.com/d/msgid/racket-users/ae981bda-94d3-43d2-ae23-a41f5160aa0ao%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/CADcuegv8EPsUjHmLq9uDDXRK2u0p%3D7zdU3XcMdqtA_9jr_%2BXzw%40mail.gmail.com.

