[racket] Catching lifts and let

From: Asumu Takikawa (asumu at ccs.neu.edu)
Date: Thu Jul 24 16:32:58 EDT 2014

Hi all,

I have a question about syntax lifting and catching those lifts. Here's
an example program that illustrates my concern:

  #lang racket

  ;; do the lifting
  (define-syntax (m stx)
    (syntax-local-lift-expression #'(+ 1 1)))

  ;; catch the lift, try to put definitions in a let
  (define-syntax (catch stx)
    (syntax-case stx ()
      [(_ body ...)
       (syntax-case (local-expand/capture-lifts #'(body ...) (syntax-local-context) null)
         (define-values begin)
         [(begin (define-values (x ...) e ...) ... exp)
          #'(let () (define-values (x ...) e ...) ... exp)])]))

  (catch (+ 1 (m)))

I'd like this program to work and produce `3` in the end, but it produces an
unbound identifier error.

The trouble is that when a syntax lift is done, the identifier produced
by the lift is a top-level identifier and gets wrapped with #%top. That
means that putting the caught definitions in a `let` can't work, because
those become local let-bindings.

In the example above, the relevant excerpt of the expansion is this:

  (letrec-values (((lifted.0) (#%app + '1 '1))) ; does not bind below
    (#%app (#%app + '1 (#%top . lifted.0))))

Does the design of syntax lifting preclude this kind of macro
interaction?

Cheers,
Asumu

Posted on the users mailing list.