[racket-dev] submodules

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Fri Mar 9 19:15:31 EST 2012

At Fri, 9 Mar 2012 16:35:25 -0500, Eli Barzilay wrote:
> Two days ago, Matthew Flatt wrote:
> > 
> > Given the term "submodule", the first thing that you're likely to try
> > will work as expected:
> > 
> >   #lang racket/base
> > 
> >   (module zoo racket/base
> >     (provide tiger)
> >     (define tiger "Tony"))
> > 
> >   (require 'zoo)
> > 
> >   tiger
> > 
> > Within `module', a module path of the form `(quote id)' refers to
> > the submodule `id', if any. If there's no such submodule, then
> > `(quote id)' refers to an interactively declared module, as before.
> This is *really* nice in how it's building a scope for module names,
> but OTOH, it makes the quote seem more like a syntactic hack...


> >   [...later...]
> > 
> >   (require (submod 'zoo monkey-house))
> > 
> > [...] a shorthand for `(submod "." zoo)' [...]
> ...especially here -- why is there a quote only on the first and not
> on the second?

That jumped out at me, too. But the first is a module path and the
second is a submodule name. For example,

  (submod zoo monkey-house)

would mean the `monkey-house' submodule of "main.rkt" from the "zoo"
collection, not a `monkey-house' subsubmodule in a `zoo' submodule.

>  Is there any meaning for (submod foo) without the
> quote (or a sting)? 

We could allow

   (submod foo)

as equivalent to


that is, as a reference to `foo' with an empty submodule path.

> Perhaps a more obvious question is why aren't all `submod' uses get
> "." as an implicit first expression? 

I don't see how lets you reach a submodule from the top level or from
within a different top-level module.

> > The 'zoo module path above is really a shorthand for `(submod "."
> > zoo)', where "." means the enclosing module and `zoo' is its
> > submodule. You could write `(submod "." zoo monkey-house)' in place
> > of `(submod 'zoo monkey-house)'.
> I also love the analogy to paths -- but using strings for them doesn't
> look so nice, since strings are begging to be combined...  (I can
> already see myself wishing for "./../foo".)  Other than the obvious
> reader issue, would there be a problem in using `|.|' and `..' for
> these (and making them into special module names)?

Submodule identifiers are not currently constrained, and I think we
should avoid constraining them. If we refrain from constraining
submodule names, then `..' could be the name of a submodule.

> How about just (submodule foo ...) be a more
> memorable syntax for (module* foo #f ...)?

That was Jon's suggestion, and my objection is that "submodule" means
something more general than those nested modules that are declared with

> taking what Jay did (I think, didn't look at the code or the
> followups, yet), and making this:
>   (submodule <name> E ...)
> be something that can appear anywhere in the code, expands to what
> (module* main #f E ...) is doing now, *and* is allowed to be used more
> than once, with all uses being collected into a single submodule.

Yes, I think this is a promising direction, and we just need to find a
better name than `module**'. I'll leave that discussion to the other

> > The `#lang' reader form was previously defined as a shorthand for
> > `#reader' where the name after the `#lang' is mangled by adding
> > "/lang/reader".  With submodules, `#lang' first tries using the name
> > as-is and checking for a `reader' submodule; if it is found, then
> > the submodule is used instead of mangling the name with
> > "/lang/reader", otherwise it falls back to the old behavior.
> (BTW, there's an obvious question here of why not do that for all
> paths, so that `foo/bar/baz' can access a `bar/baz' submodule in `foo'
> or a `baz' in `foo/bar'...

Search paths cause lots of trouble and should be avoided when possible.
This particular two-step search seem to be just barely tolerable for
`#lang', and I still worry about it; I wouldn't suggest it if I saw a
better way to accommodate existing code.

Posted on the dev mailing list.