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

From: Alexander D. Knauth (alexander at knauth.org)
Date: Thu Jul 10 12:56:07 EDT 2014

Ok now it does this:

#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?

On Jul 10, 2014, at 11:51 AM, Matthew Flatt <mflatt at cs.utah.edu> wrote:

> I think the problem may be in `at-exp`.
> 
> 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?
> 
> At Thu, 10 Jul 2014 11:30:18 -0400, "Alexander D. Knauth" wrote:
>> 
>> On Jul 10, 2014, at 6:40 AM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
>> 
>>> 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.
>> 
>> Well for some reason it doesn’t:
>> #lang afl at-exp racket/base
>> (map #λ(+ % 1) '(1 2 3)) ; read: bad syntax `#λ’
>> 
>> But also for some reason this does:
>> #lang at-exp afl racket/base
>> (map #λ(+ % 1) '(1 2 3)) ; '(2 3 4)
>> (map #λ@+[% 1] ‘(1 2 3)) ; ‘(2 3 4)
>> By the way I only just got this to work yesterday by doing basically this but 
>> for afl:
>> https://github.com/AlexKnauth/rackjure/commit/5fa266e672d529dde227ef216aaef157fa
>> 5c618c
>> 
>> Also is there any way to get something like this to work?:
>> #lang afl at-exp racket/base
>> @#λ(+ % 1)[1] ; read: bad syntax `#λ'
>> 
>>> 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.
>> 
>> Do you mean like this?:
>> (define lambda-readtable (current-readtable))
>> (parameterize ([current-readtable orig-readtable])
>>  (read-syntax/recursive src in #f lambda-readtable))
>> 
>>> 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).
>> 
>> Ok I just found this in section 1.3.18:
>> The arity of the resulting procedure determines whether it accepts extra 
>> source-location information: a read procedure accepts either one argument (an 
>> input port) or five, and aread-syntax procedure accepts either two arguments (a 
>> name value and an input port) or six. In either case, the four optional 
>> arguments are the reader’s module path (as a syntax object in read-syntax mode) 
>> followed by the line (positive exact integer or #f), column (non-negative exact 
>> integer or #f), and position (positive exact integer or #f) of the start of the 
>> #reader form. 
>> 
>> But maybe there should be a link or something to section 1.3.18 from sections 
>> 17.2 and 17.3.1 of the Guide.  
>> That would make it a lot easier to find it.  
>> 
>>> 
>>> 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
>> 
>> ____________________
>>  Racket Users list:
>>  http://lists.racket-lang.org/users



Posted on the users mailing list.