I agree. Thanks, Robby
On Fri, May 16, 2014 at 11:37 AM, Matthew Flatt <[email protected]> wrote: > At Fri, 16 May 2014 08:59:12 -0500, Robby Findler wrote: >> I think I'm still missing a step here because changing the set! in >> funny-set! to a reference makes the "is it an expression" sensitivity >> go away (the reference works in both cases), but the explanation would >> seem to still apply. > > That's puzzling... > >> Is there something special about set!s that is >> contributing here? > > It seems that I had made the corner smaller (and even more awkward?) > with an extra check for variable references in the special case that > the variable is bound in the enclosing module. I can put the same check > in place for `set!`; I'm not sure that's a good idea, since it's not a > general repair, but probably it's better for `set!` to be consistent > with variable reference. > > >> On Fri, May 16, 2014 at 1:47 AM, Matthew Flatt <[email protected]> wrote: >> > You're running into an awkward corner of the macro system. The corner >> > has to do identifiers that are produced by `generate-temporary` and >> > then defined within a module. >> > >> > An identifier produced by `generate-temporary` doesn't claim to be from >> > any particular context. If such identifier is defined within a module >> > M, how do other uses of the identifier know to refer to the definition >> > of M (since the identifier by itself doesn't claim to be from M)? >> > >> > The answer is that the definition marks the identifier as "introduced >> > by a macro into M". It also marks each top-level form in a module with >> > the "introduced to module M" context after expansion. The "top-level" >> > modifier on "form" is crucial here. >> > >> > When you wrap `(funny-set! 3)` with `(void ...)`, then you delay its >> > expansion until after all top-level forms are expanded. That is, >> > `funny-set!` is not long a top-level form within the module. >> > >> > * If there's no `void`, then the `funny-set!` form is expanded, and >> > the introduced variable is marked with the "introduced to M" >> > context, and that matches up with the definition. >> > >> > * If there's a `void`, then the `(void (funny-set! 3))` form as a >> > whole is marked with "introduced into M", but the `funny-set!` macro >> > is not expanded, yet. Later, when `funny-set!` is expanded as a >> > nested expression, then the introduced identifier is *not* marked >> > with "introduced to M", and so it doesn't match up with the >> > definition. >> > >> > I'm itching to try a new macro expander that I think would solve this >> > problem, and maybe that will happen sometime this year. >> > >> > Meanwhile, I would write `make-funny-set` as >> > >> > (define-syntax (make-funny-set! stx) >> > (syntax-parse stx >> > [(_ v) >> > (define unmarked (generate-temporary)) >> > #`(begin >> > (begin-for-syntax (set! funny (quote-syntax #,unmarked))) >> > (define #,unmarked v))])) >> > >> > and also >> > >> > (define-syntax (funny-set! stx) >> > (syntax-parse stx >> > [(_ v) >> > #`(set! #,funny v)])) >> > >> > By expanding into `begin-for-syntax`, you get the macro expander to >> > help you a little more: you don't have to use `syntax-local-introduce`. >> > Also, you also avoid the awkward corner, because the still-quoted >> > identifier is visible to the macro expander (and therefore available >> > for the "introduced to M" mark) instead of sitting in a side channel. >> > >> > At Thu, 15 May 2014 16:25:47 -0500, Spencer Florence wrote: >> >> I'm attempting to write a macro which introduces a new id, then another >> >> macro that set!s that id. >> >> Example: >> >> >> >> #lang racket >> >> (require (for-syntax syntax/parse racket/syntax)) >> >> (define-for-syntax funny #f) >> >> (define-syntax (make-funny-set! stx) >> >> (syntax-parse stx >> >> [(_ v) >> >> (define unmarked (generate-temporary)) >> >> (set! funny (syntax-local-introduce unmarked)) >> >> #`(define #,unmarked v)])) >> >> (define-syntax (funny-ref stx) >> >> (syntax-parse stx >> >> [(_) >> >> funny])) >> >> (define-syntax (funny-set! stx) >> >> (syntax-parse stx >> >> [(_ v) >> >> #`(set! #,(syntax-local-introduce funny) v)])) >> >> >> >> (make-funny-set! 2) >> >> (funny-set! 3) >> >> (funny-ref) >> >> >> >> This program works as I expect, evaluating to 3. However if I change >> >> (funny-set! 3) to (void (funny-set! 3)) I get the error: "set!: unbound >> >> identifier in module in: g1" >> >> >> >> I do not get this error if I change (funny-ref) to (void (funny-ref)). >> >> >> >> If I look at the expansion of the (void (funny-set! 3)) program in >> >> drracket's macro stepper the the g1 in (define g1 2) and the g1 in (void >> >> (set! g1 3)) have the same color. >> >> >> >> To keep on with the strange, if I change the #,(syntax-local-introduce >> >> funny) inside of funny-set! to #,funny inside the behavior of all programs >> >> remains the same. >> >> >> >> Could someone explain whats going on? >> >> >> >> --Spencer >> >> ____________________ >> >> Racket Users list: >> >> http://lists.racket-lang.org/users >> > ____________________ >> > Racket Users list: >> > http://lists.racket-lang.org/users ____________________ Racket Users list: http://lists.racket-lang.org/users

