[racket] local-expand and stop-lists?

From: Sam Tobin-Hochstadt (samth at ccs.neu.edu)
Date: Fri Aug 12 14:08:43 EDT 2011

On Fri, Aug 12, 2011 at 1:58 PM, Ryan Culpepper <ryan at cs.utah.edu> wrote:
> On 08/12/2011 11:37 AM, Sam Tobin-Hochstadt wrote:
>> On Fri, Aug 12, 2011 at 1:25 PM, Danny Yoo<dyoo at cs.wpi.edu>  wrote:
>>> In which the first three lines are coming from compile-time, and I see
>>> that my lift-to-toplevel macro is firing off, even though I placed it
>>> in the stop-list of local-expand.
>> What's happening here is that the `#%module-begin' binding from
>> `racket/base' calls `local-expand' on each of its forms, to determine
>> whether its an expression or not.  This implements the printing of
>> top-level expressions.  If you replace `#%module-begin' with
>> `#%plain-module-begin', you should see the desired behavior.
> '#%plain-module-begin' also calls 'local-expand' to expose definitions,
> requires, etc. When I change Danny's sample code to use
> '#%plain-module-begin' instead of '#%module-begin', I get the same output.

`#%plain-module-begin' doesn't seem to explicitly call `local-expand',
in the sense that the Macro Stepper shows.  For example, this program:

(module m racket
  (#%plain-module-begin (#%expression 3) 4))

when macro-stepped, shows no local-expand steps, but this program:

(module m racket
  (#%module-begin (#%expression 3) 4))

does show local-expansion steps.

> In general, when a 'local-expand' happens inside of another 'local-expand',
> the outer stop list is discarded. Since '#%plain-module-begin' effectively
> calls 'local-expand', I would expect the #'lift-to-toplevel stop list to
> never have any effect.

That's not quite true.  This program shows the difference between
having it in the stop-list and not:

(module e 'small-lang
  (printf "hello world\n")
  (#%expression (lift-to-toplevel (printf "ok!"))))

In general, if `lift-to-toplevel' is an expression form, then I'd do

(define-syntax-rule (lift-to-toplevel-aux . rest)
  (#%expression (lift-to-toplevel . rest)))

Which I think would fix the problem (even for `racket/base's `#%module-begin').

If it needs to be a top-level form, more tricks are needed.
sam th
samth at ccs.neu.edu

Posted on the users mailing list.