[racket] How to make an identifier that will have a certain binding no matter what phase level it's referenced at?

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Mon Jul 28 02:05:53 EDT 2014

It's not just a question of having `lambda` bound at the right phase,
but also of ensuring that the module implementing `lambda` is
instantiated at the right time and phase. The `require` form takes care
of both jobs, and the fact that it binds and creates an instantiation
dependency at the same time is the key to making things work naturally.

So, being able to give an identifier context when it's produced by
`read` may be part of the eventual solution, but I think there's still
a piece of the puzzle that we haven't found. Along similar lines, I
think that cross-phase persistent modules may be a piece of the
solution, but I don't think they're enough by themselves.

I recommend against giving a `read-syntax` result a non-empty lexical
context, but my main answer is "I don't know". I think we may be close
to an answer, but I'm hoping that someone gives this a fresh look
eventually.

At Sun, 27 Jul 2014 19:24:26 -0400, "Alexander D. Knauth" wrote:
> 
> On Jul 27, 2014, at 1:20 PM, Roman Klochkov <kalimehtar at mail.ru> wrote:
> 
> > It is bound to racket/base lambda. More correct, phase0 lambda in racket/base.
> > But when you call it in level 2, there are no level 0 lambda.
> > 
> > Minimal similar test-case:
> > ---------------
> > (module m racket/base
> >   (provide test-stx)
> > 
> ;; what you need here is this:
> (require (for-template racket/base))
> >   (define (test-stx) #'(lambda (x) x)))
> > 
> > (require (for-syntax 'm))
> > 
> > (define-syntax (test stx) (test-stx))
> > 
> > test
> > 
> 
> Then it works fine.  But since #λ is a reader extension, not a macro, it could 
> be at any phase level.  
> I was wondering if there’s any way to construct an identifier that would be 
> bound to lambda from racket/base
> no matter what phase level it’s referenced at.  
> These examples with macros only have to make sure that it’s there at the 
> for-template phase level relative to test-stx.  
> A reader extension doesn’t have that constraint.  
> > 
> > . lambda: unbound identifier;
> >  also, no #%app syntax transformer is bound in: lambda
> > ----------------
> > 
> > Minimal correct case:
> > ------------------
> > (module m racket/base
> >   (provide test-stx)
> >   (define (test-stx a l)
> >     (with-syntax ([#%app a]
> >                   [lambda l])
> >       #'(lambda (x) x))))
> > 
> > (require (for-syntax 'm))
> > 
> > (define-syntax (test stx) (test-stx #'#%app #'lambda))
> > 
> > test
> > --------------------
> > 
> > So you have to somehow give correct #'lambda and #'#%app into your macros.
> > 
> > 
> > Sun, 27 Jul 2014 12:21:36 -0400 от "Alexander D. Knauth" 
> <alexander at knauth.org>:
> > 
> > I just tried to try it and see if it worked, when I realized that it won’t 
> work because I can’t use quote-syntax.  
> > 
> > Is there any way to get around that?  And would it even work anyway?  
> > 
> > On Jul 27, 2014, at 6:59 AM, Roman Klochkov <kalimehtar at mail.ru> wrote:
> > 
> >> Maybe via "Cross-Phase Persistent Module Declarations" 
> http://docs.racket-lang.org/reference/syntax-model.html#%28part._cross-phase._pe
> rsistent-grammar%29 ?
> >> 
> >> 
> >> Thu, 24 Jul 2014 21:24:20 -0400 от "Alexander D. Knauth" 
> <alexander at knauth.org>:
> >> How can I make an identifier that will have a certain binding no matter what 
> phase level it's referenced at?
> >> 
> >> For example if I’m making a reader extension that will produce a lambda 
> expression, how do I make it so that the lambda expression will be able to 
> exist at any phase level?
> >> 
> >> For example this program using #lang rackjure doesn’t work:
> >> #lang rackjure
> >> (require (for-meta 1 racket/base)
> >>          (for-meta 2 racket/base)
> >>          (for-meta 3 racket/base)
> >>          (for-meta 4 racket/base)
> >>          )
> >>                                                  
>                                             
> >> #λ(* 2 %) ; works, produces approx. (lambda (%) (* 2 %))
> >> (begin-for-syntax
> >>   (begin-for-syntax
> >>     #λ(* 2 %) ; lambda: unbound identifier at phase 2;
> >>     ;         ;   also, no #%app syntax transformer is bound in: lambda
> >>     ))
> >> 
> >> Is there any way to construct an identifier that would be bound to lambda 
> from racket/base no matter what phase level it’s used in?
> >> 
> >> 
> >> ____________________
> >>   Racket Users list:
> >>   http://lists.racket-lang.org/users
> >> 
> >> 
> >> 
> >> -- 
> >> Roman Klochkov
> > 
> > 
> > 
> > -- 
> > Roman Klochkov
> 
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users


Posted on the users mailing list.