[plt-dev] syntax-local-value and identifier-mappings
At Mon, 9 Mar 2009 16:15:46 -0400, Sam TH wrote:
> Right now, `syntax-local-value' cooperates with
> `make-rename-transformer' to 'do the right thing'. However, it's not
> possible to build any other abstractions with the same property, since
> you can't get out the target of a rename transformer (you can't even
> tell that an identifier is bound to one). It would be nice if
> `syntax-local-value' took an additional argument to specify that it
> shouldn't loop, so that other abstractions could be built that
> respected rename-transformers.
I've tried this before, following much the same rationale. It turned
out not to solve the problems that motivated it before, though, and so
I removed that capability in an attempt to keep renaming more abstract.
In particular, making intermediate names accessible might provide
access to a scope that is otherwise unavailable (by taking a
intermediate identifier's context and transferring it to a different
symbol).
At the same time, I agree that `make-rename-transformer' isn't right.
One place this show up is in the package system, where opening a
package doesn't give you the same bindings in terms of
`free-identifier=?':
(define-package p (x y)
(define-syntax x
(syntax-rules (y)
[(x y) 'y]
[(x z) 'other]))
(define y 'placeholder))
(let ()
(open-package p)
(x y)) ; => 'other, instead of 'y
That's because `open-package' introduces new bindings to rename
transformers, instead of actually splicing the bindings from the
package.
> Typed Scheme is implemented using a free-identifier-mapping that
> associates type names with types. This has the nice property that it
> cooperates with the module system to track arbitrary requires,
> provides, and renamings. Unfortunately, it breaks in the presence of
> rename transformers.
This sounds like the same problem as for `open-package'. You don't
specifically need to walk the links. You need a truer renaming --- one
that works with `free-identifier=?'. Right?
Ideally, the renaming should work at the level of syntax objects, where
`free-identifier=?' lives, instead of at the level of transformer
bindings.
One possibility is a `define-renaming' form that adjusts bindings at
the syntax-object level. That seems like the right thing at some level,
but then we'd end up with a zoo of syntactic forms for local binding,
etc. Also, it would require converting existing code.
Another possibility is to have `free-identifier=?' inspect transformer
bindings in the current scope, so that it would effectively walk a
renaming chain in the same way as `syntax-local-value'. That would work
with existing code, but move `free-identifier=?' out of the pure
syntax-object level means that it wouldn't work quite always, and it
might make comparisons significantly more expensive.
One last possibility, which I had not really considered until now, is
to have the macro expander treat a transformer binding to a renamer by
applying a syntax-object renaming immediately, instead of merely
installing a transformer binding. That sounds promising to me, and I
could give it a try next week or so.