[racket-dev] Trouble with state, submodules, and module-begin

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Mon Jul 2 09:22:21 EDT 2012

Is it possible there is another channel that TR could use to
communicate these types? That is, could it not expand

  (: f Integer)
  (define f 5)

into something that bound 'f' to a macro that knows its type? I guess
it already does that, so something doesn't work about that here, but
I'm not seeing what it is.


On Mon, Jul 2, 2012 at 8:07 AM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
> Thoughts so far:
> I think you need a new communication channel to get information from
> the expansion of an enclosing module to the expansion of its submodule.
> Expansion-time state is the right kind of channel, but I think it's
> important to start every submodule's expansion in a fresh store, at
> least usually. Otherwise, many syntactic extensions won't work
> correctly in a submodule.
> To give the programmer more control, we could add a
> `local-expand-submodule' function that is like `local-expand', but (1)
> it works only for `module' and `module*' forms in a 'module context,
> and (2) it accepts module paths to attach from the current expansion
> context to the submodule's expansion context.
> Using this addition, when expanding a `(module* name #f ....)'
> submodule, Typed Racket could attach a compile-time module that houses
> the "in a typed context" flag --- the same one that Typed Racket's
> `#%module-begin' sets. Does it sound like that would work?
> I worry that `local-expand-submodule' might be used to break a
> syntactic form by attaching a module that isn't intended to be attached
> to multiple expansion stores. I think a macro that abuses
> `local-expand-submodule' could only harm itself or some other module
> that trusts the macro, but it's difficult to be sure.
> At Mon, 25 Jun 2012 16:47:36 -0600, Matthew Flatt wrote:
>> At Mon, 25 Jun 2012 17:50:27 -0400, Sam Tobin-Hochstadt wrote:
>> > The problem (I
>> > think) is that the implicit `require` of `(submod "..")` happens
>> > *before* the expansion of `#%module-begin` inside the submodule.
>> That's the same for a top-level module M whose initial language is some
>> other module L, right? The require of `L' happens before the
>> `#%module-begin' expansion in `M'... and it can't be any other way,
>> because `#%module-begin' comes from `L'.
>> > The
>> > key bit of code is the residual snippet left in the outer module:
>> >
>> >          (begin-for-syntax
>> >              (when (unbox is-typed?)
>> >                (set-box! type-env 1)))
>> >
>> > Currently, in TR, the code in the begin-for-syntax is unconditional,
>> > and therefore it gets re-run in the store used for expanding the inner
>> > submodule.  However, if I add the `when`, then the `set-box!` doesn't
>> > happen, and the expansion of `m` fails.  I'd like to be able to add
>> > this conditional, so I'd like to change the order of effects slightly
>> > here.
>> I see what you mean, but I don't think it makes sense to change the
>> order of things in the way that you're suggesting. I don't have any
>> immediate ideas, but I'll think about it more.
>> _________________________
>>   Racket Developers list:
>>   http://lists.racket-lang.org/dev
> _________________________
>   Racket Developers list:
>   http://lists.racket-lang.org/dev

Posted on the dev mailing list.