[racket-dev] submodules

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Thu Mar 8 16:17:57 EST 2012

At Thu, 8 Mar 2012 15:41:38 -0500, Asumu Takikawa wrote:
> This sounds great! I haven't tried it out yet, but here are some
> preliminary comments.
> On 2012-03-07 10:14:35 -0700, Matthew Flatt wrote:
> > Submodules declared with `module' are declared locally while expanding
> > a module body, which means that the submodules can be `require'd
> > afterward by the enclosing module. This ordering means, however, that
> > the submodule cannot `require' the enclosing module.
> >
> > [...]
> >
> > The `module*' form is like `module', but it can be used only for
> > submodules, and it defers the submodule's expansion until after the
> > enclosing module is otherwise expanded. As a result, a submodule using
> > `module*' can `require' its enclosing module, while the enclosing
> > module cannot require the submodule.
> It seems to me that `module*` maybe actually be the common case for
> submodules because most of the time I would expect that you want to use
> the bindings of the enclosing module. This seems true for unit tests,
> driver modules, documentation (requiring for-template), and so on.
> Would it make sense to swap the `module` and `module*` forms?

That's how it was at first, but I didn't like how

 (module m racket/base)
 (require 'm)

was completely different at the top level and within a module.

Although the correspondence between `module' at the top level and
within a `module' is only approximate, it makes things much easier to
explain. It's also easier to explain that `#f' is allowed as the
language of a `module*', which is always a submodule, and `#f' is never
allowed as the language of `module'.

(In fact, there was no nested `module' until the last few hours before
my post. I had `module*' as `module', and it was starting to look
difficult to explain... Realizing that nearly everything was in place
to support nested `module' in addition to `module*' was my biggest
"aha!" moment.)

> Another aspect of the syntax that I foresee being annoying is that each
> module nesting adds an additional indentation level. On the other hand, I
> don't see any good alternative for this. I only bring this up because
> this was problematic enough in the past to invent the #lang shorthand.

I don't think that explicit `module' or `module*' forms will be that
common. Instead, I expect that they'll mostly be generated by macros,
such as a `main' macro or Jay's `define-test' macro. But if they become
common, or if we often want to re-export an external module via a
submodule, then we should revisit this point.

Posted on the dev mailing list.