[racket] meta-languages and going back to the "normal" reader

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Thu Jul 10 06:40:25 EDT 2014

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).

At Sat, 5 Jul 2014 13:33:27 -0400, "Alexander D. Knauth" wrote:
> 
> If I have a meta-language like this:
>  #lang my-meta-lang <language>
> And my-meta-lang is similar to at-exp in that it can accept any arbitrary 
> language with any arbitrary reader
> (as long as it looks at the readtable), then how do I escape back to the reader 
> specified by <language>
> from inside a reader macro from my-meta-lang?
> 
> 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


Posted on the users mailing list.