[racket-dev] submodules

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sun Mar 11 11:52:55 EDT 2012

At Sat, 10 Mar 2012 18:26:52 -0500, Eli Barzilay wrote:
> > > 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.
> So, this is the bit that wasn't clear to me in your original email.  I
> now see that this code works:
> | #lang racket/load
> | 
> | (module my-code racket/base
> |   (module private racket/base
> |     (provide secret)
> |     (define secret 1))
> |   (require 'private)
> |   (provide public)
> |   (define public (list secret)))
> | 
> | (module hacker racket/base
> |   (require (submod 'my-code private))
> |   (printf "The secret is ~a\n" secret))
> | 
> | (require 'hacker)
> Isn't this kind of code something that doesn't have a real use,
> perhaps other than some reflection stuff (like repl uses)? 

If I understand what you mean, then all of the interesting uses I see
involve extracting a submodule from the outside:

 * Extracting the `reader' submodule of a given module.

 * Running a `main' submodule of a given module.

 * Running a `test' submodule of a given module.

 * Getting documentation information for a given module.

 * Getting "extra exports" of a given module.

I expect submodule references across top-level modules, as in your
example above, to be relatively rare, but that's what would happen for
getting "extra exports". Also, a reader for language X might want to
just re-export the reader for language Y.

> I first
> thought that the whole point of allowing a sub-`module' would be to
> have some otherwise-inaccessible private code in it (as the fictitious
> author of that `my-code' module thinks). 

That is indeed not the goal. But it works the other direction with
`(submodule* ... #f ....)': the enclosing module can have
otherwise-inaccessible code that is accessed by the submodule (e.g., to
test unexported functions).

> If that's wasn't possible,
> or possible only as a some semi-obscure-reflection-api then the
> `submod' syntax could be simpler.

I'm not sure what you mean here

> > > 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.
> It just seems similar to the old ("lib.ss" "some" "path") thing in
> that it's asking to be changed to something that is easier to
> remember.  Maybe make ".." have an implicit "." before it so there's
> no need for a mysterious `"." ".."'?

Yes, I think `(submod ".." <elem> ...)' can be a shorthand for `(submod
"." ".." <elem> ...)'. I see no way to handle it other than as a
special case, but that seems ok.

Posted on the dev mailing list.