At Tue, 29 Sep 2015 22:06:45 -0500, Brian Mastenbrook wrote:
> On 09/29/2015 09:23 PM, Matthew Flatt wrote:
> > When you step back, it sure looks non-hygienic, because
> >
> >   (define-syntax-rule (def-and-use-m given-x)
> >     (begin
> >       (define-syntax-rule (m)
> >          (begin
> >            (define given-x 'inner)
> >            x))
> >       (m)))
> >
> > looks like a reference to a `x` that should never be captured by any
> > `given-x`. The catch is that it's a free `x` with respect to the
> > context of `def-and-use-m`. In a context that allows both a definition
> > and a use of `def-and-use-m`, it can turn out that `given-x` is exactly
> > the identifier that the free `x` should refer to.
> 
> I'm afraid I'm still not following. To avoid confusing myself with 
> multiple issues, I'll start with a version of `m' that does not involve 
> splicing:
> 
> (define x 'outer)
> 
> (define-syntax-rule (def-and-use-m given-x)
>    (begin
>      (define-syntax-rule (m)
>        (let ()
>          (define given-x 'inner)
>          x))
>      (m)))
> 
> (def-and-use-m x)
> 
> As before, the old expander returns `outer' and the new expander returns 
> `inner'.
> 
> The reason that this seems to violate hygiene to me is that if I change 
> the definition of `m' to an ordinary procedure definition, I get 'outer 
> from both expanders. It seems to me to be the very essence of hygiene 
> that lexical capture works in macros the same way that it works in 
> ordinary definitions, and I'm surprised that such minor transformations 
> of the program are affecting the result in ways that don't seem to match 
> my mental model for how things "should" work.

You're right, and I was confused in my response before. Whether the
definition of `given-x` is splicing should matter, and 'outer is the
correct result above.

I'm fixing a bug in the implementation's handling of use-site scopes,
and that makes your example above work correctly. The bug is a holdover
from an earlier, broken idea of how to handle use-site scopes. Getting
rid of it --- bringing the implementation in line with the paper ---
solves the problem while the core test suite still passes and the main
distribution builds.

Thanks very much for pushing through the details and making sure the
implementation is right!


I think the examples in the paper are still correct, and it's still the
case that

 (let ()
   (def-m m x)
   (m))

resolves the ambiguity. However, with the repaired expander, it's also
the case that

 (def-m m x)
 (let ()
   (m))

resolves the ambiguity, in contrast to my earlier response. The
ambiguity depends (as originally intended) on a single definition
context shared by `def-m`, `m`, and `given-x`.

Similarly, it's still the case that

 (define x 'outer)

 (define-syntax-rule (def-m m given-x)
   (define-syntax-rule (m)
     (begin
       (define given-x 'inner)
       x)))

 (def-m m x)
 (m)

produces 'inner with the new expander and 'outer with the old one.
Again, though, the result is 'outer when adding a `(let () ....)`
around the last two lines, around just the `(m)`, or in place of the
`(begin ....)` within the definition of `m` --- any of which introduces
a more nested context for the definition of `given-x`.

-- 
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/20150930125537.33EF46501D9%40mail-svr1.cs.utah.edu.
For more options, visit https://groups.google.com/d/optout.

Reply via email to