Matthew Flatt on Racket Submodules

A blog post on the Racket Blog describes Racket newly-added submodules, along with interesting use cases.

Submodules provide nested namespaces, but that kind of nesting is already available through forms like define-package. The power of submodules is that they can be separately loaded and separately run relative to their enclosing modules, in the same way that top-level modules can be separately load and run. This separation of dependencies means that submodules can be used to add code and information to modules—such as tests, documentation, and parsing information—that is loaded only when specifically requested.


At some level, syntactic nesting of modules is an obvious feature to include in a module system. Nevertheless, Racket’s submodules are not like nested modules most languages—including Python, Chez, or ML—where nesting is for namespace management and nested modules are always instantiated in along with the enclosing module. Racket submodules can be used in a similar way, but the fact that submodules are separately loadable makes them available to solve a larger class of problems.

If I had to pick just one analogy, I’d say that submodules are most like a generalization of annotations in the Java sense. Java annotations allow the decoration of code with metadata, and the annotations are preserved through run time, so that annotations can be inspected in source, in compiled code, or reflectively at run time. Java annotations are limited to data, so that any abstraction or programatic interpretation of the data depends on yet another external tool and language, or else the code part (such as test to run for a @Test annotation) is difficult to separate from the main program. C# attributes are slightly more general, in that the data can have associated methods, but attribute code is still mingled with run-time code. Submodules generalize annotations to make them “live,” so that the language of annotations can include expressions, functions, and even syntactic extensions, while allowing the annotation/submodule code to stay separate from the base code.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

The idea of loading a submodule only in some conditions

The idea of loading a submodule only in some conditions is good (will copy that), but I don't think interleaved module* used as a kind of annotation is a very good idea.

Do you have any specific

Do you have any specific reason why it's not a good idea? It works very nicely in practice, in our experience so far.

How does the interleaved

How does the interleaved module interact with the hosting module?

What I can come up with seems rather messy, and in fact, the examples proposed do not make me think this is resolved in your implementation. For example, how do you add a field to a structure or change the signature of a function?

The interleaving is entirely

The interleaving is entirely a part of the module+ macro, it's not built-in.

As for how submodules interact, they work like regular modules, in that they can be either provided to, or required by, the enclosing modules.

The implementation is available, and if you thing something doesn't work, please mention it.

Finally, I don't understand at all what you mean about adding fields or changing functions.