[racket-dev] submodules

From: Eli Barzilay (eli at barzilay.org)
Date: Sat Mar 10 18:26:52 EST 2012

Yesterday, Matthew Flatt wrote:
> At Fri, 9 Mar 2012 16:35:25 -0500, Eli Barzilay wrote:
> > 
> > >   (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.

Ah, it wasn't clear that `submod' can access submodules in other
modules.  (This raises another issue which I'll continue below.)

In any case, that quote still bugs me...  It makes more sense to me to
require quotes on all of the submodule parts, but that looks worse.
Maybe the problem is that it looks like the syntax is (submod X ...)
for equal Xs, but it's really (submod X Y ...).  This suggests a
solution that makes the above (submod zoo monkey-house) less
convenient (and I expect it to be fairly uncommon--?) -- something

  (submod (real-module zoo) monkey-house)

Can something like that work out better?  (With some proper name
instead of `real-module', of course.)

> >  Is there any meaning for (submod foo) without the
> > quote (or a sting)? 
> We could allow
>    (submod foo)
> as equivalent to
>     foo
> that is, as a reference to `foo' with an empty submodule path.

This seems like a sensible thing to do, given my current

> > 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)?  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).  If that's wasn't possible,
or possible only as a some semi-obscure-reflection-api then the
`submod' syntax could be simpler.

> > 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 `"." ".."'?

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Posted on the dev mailing list.