Composability of internal def. context and caching/lifting

20 views
Skip to first unread message

Asumu Takikawa

unread,
Aug 22, 2015, 4:20:14 PM8/22/15
to Racket Dev
Hi all,

I found a situation where internal definition contexts and lifting/caching
don't seem to compose well. Does anyone have any advice on a macro technique to
use here?

Here's a specific example to illustrate what I mean:

#lang racket

;; lift CCR
(define-syntax (do-lift stx)
(if (eq? (syntax-local-context) 'expression)
(syntax-local-lift-expression #'current-contract-region)
#`(#%expression #,stx)))

;; delayed expansion of lifted ref causes problems
(define (f x)
(do-lift) ; this is ok if it comes afterwards
(define y current-contract-region)
(void))

This results in an undefined id error. It happens even though `do-lift` is
written to be careful about delaying lifting in an internal def. context.

The `current-contract-region` id macro uses syntax lifting and a compile-time
hashtable to cache the expanded definition.

The macro `do-lift` does a lift of a use of `current-contract-region`, delaying
the lift for internal def contexts.

The problem is when these two macros get used in `f`. The lift by `(do-lift)`
lifts a `current-contract-region` use, but this use isn't expanded until later
after the def. context is done.

But this means the first instance of `current-contract-region` to get expanded
is the one in the def. context, so it will set the cache first. Thus the
delayed reference in the lift will become unbound since it consults the cache.

How should I make these macros (or maybe current-contract-region) more
resilient?

Cheers,
Asumu
Reply all
Reply to author
Forward
0 new messages