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.