[racket] Managing communication between two macro invocations at the top-level

From: Asumu Takikawa (asumu at ccs.neu.edu)
Date: Sun Jul 20 18:27:20 EDT 2014

Hi all,

I'm stuck on a macro issue with the top-level and was wondering if
anyone had any thoughts.

Certain macros (I'm thinking of parts of Typed Racket) manage
communication between different parts of a program (different macros or
different instantiations of the same macro) by storing a syntax-time
table that maps, say, identifiers that should be defined in one place
and referenced in another.

The trouble is that this approach doesn't work so well at the top-level
because of the issues described in Reference §1.2.3.9. Namely because at
the top-level if one invocation of a macro expands to:

  (my-macro) =>

  (begin
    (define-values (generated-id) something-to-use-later)
    ... other stuff ...)

and then another invocation expands to:

  (my-macro) =>

  (begin
    (generated-id)
    ... other stuff ...)

you get an unbound identifier error because `generated-id` is only bound
within the first `begin` block.

Is there any way I can get around this issue? I thought maybe syntax
lifting would help out, but I need to use a particular generated
identifier and not a fresh one obtained from lifting. That and TR
catches all lifts at the top-level anyway (and sticks them in a `begin`)
so I don't think it'll help.

I also noticed that you can get around the 1.2.3.9 limitation using
`eval` if you have a non-gensymed identifier, but it doesn't appear to
help with a gensymed one.

Cheers,
Asumu

Posted on the users mailing list.