What I’m trying to do is something like #lang afl <language> where afl adds rackjure-like anonymous function literals
to <language>.
So to parse this:
#lang afl racket
#λ(+ % 1)
It would use the racket reader but wrap it to use the afl-readtable, which includes dispatch-macros that would
read the (+ % 1) and parse the result into a lambda expression.
But if <language> was something else, with a different reader, then how could I use that to read the (+ %1 1).
For example if it was something like this:
#lang afl at-exp racket
#λ@+[% 1]
There’s also another problem. If it was this:
#lang afl <language>
#f
Or this:
#lang afl <language>
#false
Or some other thing starting with f that means something to <language>,
Then it would see the #f and hope that it would turn out to be #fn. If it doesn’t, then it uses the racket reader
(instead of the one provided by <language>) to read the #f or the #false.
So back to my original question: How do I escape back to the reader specified by <language>
from inside a reader macro?
By the way I can’t find anything in the docs about what the arguments to the read and read-syntax functions
provided by <language>/lang/reader.rkt are supposed to be or mean.
____________________
Racket Users list:
http://lists.racket-lang.org/users
I think a `#lang afl at-exp racket` combination should work fine: `afl`
installs a handler for `#λ`, `at-exp` installs a handler for `@`, and
`racket` uses `read-syntax` to see both extensions.
Adding `#fn` support is a little trickier if you want to fall back to
`#f` or `#false` when the character after `#f` (as determined by a
peek) is not `n`. For that case, the readtable addition for `#f` should
remember the old readtable, and then when it needs to fall back, it
calls `read/recursive` with the saved readtable as the third argument.
That way, immediate parsing of `#f...` uses the saved readtable without
`afl` extensions, while parsing of sub-expressions will return to the
current readtable that includes the `afl` extensions.
Documentation for the functions from a "<language>/lang/reader.rkt" is
in section 1.3.18 of the Reference, which defines `#lang` (as being
"like `#reader`, which is described in the same section).
The readtable strategy works when <language> itself uses a
readtable-based reader. The idea is that you install a mapping for `#λ`
while leaving all the other mappings in place. If <language> uses a
readtable-based reader, then it picks up your extension, otherwise it
doesn't.
I think a `#lang afl at-exp racket` combination should work fine: `afl`
installs a handler for `#λ`, `at-exp` installs a handler for `@`, and
`racket` uses `read-syntax` to see both extensions.
Adding `#fn` support is a little trickier if you want to fall back to
`#f` or `#false` when the character after `#f` (as determined by a
peek) is not `n`. For that case, the readtable addition for `#f` should
remember the old readtable, and then when it needs to fall back, it
calls `read/recursive` with the saved readtable as the third argument.
That way, immediate parsing of `#f...` uses the saved readtable without
`afl` extensions, while parsing of sub-expressions will return to the
current readtable that includes the `afl` extensions.
Documentation for the functions from a "<language>/lang/reader.rkt" is
in section 1.3.18 of the Reference, which defines `#lang` (as being
"like `#reader`, which is described in the same section).
If you change
pkgs/racket-pkgs/at-exp-lib/at-exp/lang/reader.rkt
and replace the use of `at-readtable` with `(make-at-readtable)`, does
that fix the problem?
#lang afl at-exp racket/base
(map #λ@+[% 1] '(1 2 3)) ; @+: unbound identifier in module in: @+
#lang at-exp afl racket/base ; different order
(map #λ@+[% 1] '(1 2 3)) ; ‘(2 3 4)
#lang afl at-exp racket/base ; original order
@#λ(+ % 1)[1] ; 2
#lang at-exp afl racket/base ; different order
@#λ(+ % 1)[1] ; read: bad syntax `#λ’
Also for the first error it has +[ highlighted instead of @+
Is there any way to get around this?
> Ok now it does this:
>
> #lang afl at-exp racket/base
> (map #λ@+[% 1] '(1 2 3)) ; @+: unbound identifier in module in: @+
After doing the read-syntax/recursive thing now this first error goes away (I have no Idea why),
but the other ones are still the same.
> #lang at-exp afl racket/base ; different order
> (map #λ@+[% 1] '(1 2 3)) ; ‘(2 3 4)
>
> #lang afl at-exp racket/base ; original order
> @#λ(+ % 1)[1] ; 2
>
> #lang at-exp afl racket/base ; different order
> @#λ(+ % 1)[1] ; read: bad syntax `#λ’
This error is still there though.
Does at-exp use read-syntax/recursive? Would that fix this?
I don’t see why it would, but then I don’t see why it would fix the other error either.
The problem with `#lang afl at-exp` is that you need even more of a
delay: the `at-exp` reader extension currently settles on the same
readtable for recursive reading as the readtable it extends, but you
want the recursive-reading readtable to be the current one at the time
that recursive reading happens.
I've changed `at-exp` so that it delays readtable decisions to make
things work the way you expect.