At Thu, 16 Apr 2015 17:39:50 -0400, "Alexander D. Knauth" wrote:
> 
> On Apr 16, 2015, at 8:17 AM, Matthew Flatt <[email protected]> wrote:
> 
> > I don't think a "hygienic" reader extension works in the old expander,
> > either. The `lambda` produced by the `afl` or `rackjure` reader doesn't
> > reliably refer to the `lambda` from `racket/base`, because a local
> > binding for `lambda` captures the reader-produced `lambda`:
> > 
> > #lang rackjure
> > (let ([lambda 5])
> >   #λ(+ % 1)) ; => unbound `%1`
> 
> I just solved this problem for afl! (with the current macro expander)
> https://github.com/AlexKnauth/afl/commit/130216c2b85077aef893f7d0828d69394bceece
> 7

Yes, with the current expander, adding a fresh mark on the
reader-introduced identifiers makes them impossible to bind (except by
picking apart the form produced by `#λ...` to extract the special
identifiers).

Although that strategy doesn't work with the set-of-scopes expander,
you can get the same result for both expanders by making the symbolic
half of the identifier fresh, instead of the lexical-context half. That
is, with

 (define-syntax (define-unbindable-id stx)
   (syntax-case stx ()
     [(_ name id)
      (with-syntax ([gen-id (string->uninterned-symbol
                             (symbol->string
                              (syntax-e #'id)))])
        #`(begin
            (require (only-in racket/base [id gen-id]))
            (define name (quote-syntax gen-id))))]))

 (define-unbindable-id afl-lambda-id lambda)

use `afl-lambda-id` in place if `#'lambda`.


I see that you've set up `afl` so that `#λ...` will work in phases -10
to 10. I also see that `rackjure` doesn't do that, supporting only
phase 0. It may be worth noting that the change applied to `rackjure`
means that `#λ...` can no longer work in phases other than 0 (since
client code cannot introduce a suitable binding). And we'd probably
agree that `afl`'s support for specific phases is a hack. The
uninterned-symbol approach has the same limitations.


Those limitations make me feel that these approaches are the wrong
direction for a general solution. Both approaches introduce a dimension
(i.e., scopes) into reader results that isn't supposed to be at that
level, similar to the way that syntax objects are not supposed to be
"3-D". Another way to put it is that `read` is meant to work for
reading code (although with a loss of source-location information), not
just `read-syntax`.

Meanwhile, I think that reader extensions should be able to define new
kinds of literals, and those literals should work with `quote`. While
`#λ...` isn't that kind of extension, it should have a more predictable
result under `quote. But `quote` is a bigger problem for other
extensions that we've tried, such as images or quaternions.

Maybe the answer is that reader extensions produce a certain kind of
prefab struct, and something in the expander level should allow those
prefabs to be handled differently, even under `quote`. Something like
that might enable extensions that are abstract and work across phases
while also giving languages control over what kinds of values are
allowed.

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

Reply via email to