Hi Dave,

The current and old macro expanders differ on this example. I think you
can make a case for either result, but this kind of example bothers
Michael Ballantyne and William Hatch enough (on the grounds that it
should behave the old way) that they have been exploring different
notions of scope to get back the old behavior.

I don't think we've seen this specific example before, which uses a
macro defined at phase 1 to more simply provoke a difference in
expansions. Maybe Michael and William remember differently, though.

In the set of scopes model, the `x` introduced as a binding to 6 has no
extra scopes relative to the `x` introduced by the expansion of `(m2)`,
so the reference is captured by the binding. When you add `let`,
however, it introduces a scope that is not on the `x` from the
expansion of `(m2)`, so the binding to 6 doesn't capture in that case.

The mark-and-rename model of expansion, in contrast, effectively keeps
track of the order. The expansion of `(m2)` has an extra mark that
makes it ineligible for renaming by the binding of `x` to 6, even
without an extra `let` layer, so that's why the expansion of `(m2)`
produces a reference to the binding to 5.

I'm inclined to blame the discrepancy on definition contexts: the
example defines and uses `x`, `m2, and `m` all in the same definition
context, and that definition-and-use cycle creates a kind of ambiguity.
The differences that we see between the mark-and-rename and
set-of-scopes expanders are generally related to definition contexts
like that, and it's surely related to complexity in the old model [1]
that we're trying to avoid with scope sets.

Matthew

 [1] Section 3.8 of "Macros that Work Together"

At Tue, 16 May 2017 11:23:18 -0400, David Vanderson wrote:
> I'm working through "Let's Build a Hygienic Macro Expander!", which is
> great, but I'm confused about nested quote-syntax:
> 
> #lang racket
> (require (for-syntax racket))
> 
> (define x 5)
> (begin-for-syntax
>   (define-syntax m2
>     (lambda (stx)
>       #'#'x)))
> ;(let ()
>   (define-syntax m
>     (lambda (stx)
>       #`(let ((x 6))
>           #,(m2))))
>   (m)
> ;)
> 
> I think the x inside #'#'x should keep its original lexical context (prints
> 5).  But maybe quote-syntax only keeps one layer of context, so the inside
> #'x gets the context where m2 was called (prints 6)?
> 
> In DrRacket 6.9, I get 6 as shown, and uncommenting that extra let ()
> changes it to output 5, which seems fishy.  Other ways I can think of to
> write it all return 6.
> 
> Can anyone enlighten me?
> 
> Thanks,
> Dave

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-dev/591c5fd4.5a9b620a.9f3d5.2ef1SMTPIN_ADDED_MISSING%40mx.google.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to