3.1 Modules and Submodules
A module is normally written as its own file starting with #lang rhombus or similar. In an interactive context, the module form can declare a module; in that case, the module declared as id can be referenced using self!id.
A submodule is a module that is textually nested in another (sub)module using the module form. Its lifetime might be different than the enclosing (sub)module.
declaration | |||
| |||
| |||
declaration | |||
| |||
| |||
declaration | |||
| |||
| |||
declaration | |||
| |||
| |||
declaration | |||
| |||
| |||
declaration | |||
|
A ~lang is required to declare a module interactively, and ~late or ~splice is not allowed interactively.
When ~lang is not present, then the submodule’s body can refer to bindings in the enclosing module, and the submodule implicitly imports the enclosing module. The enclosing module cannot directly import the submodule, in contrast, since that would create a import cycle. The same id can be declared multiple times this way using module, and all of the body forms for the same id are combined (in the order as the appear) to create one submodule. The expansion of the body forms is delayed until the enclosing module is fully expanded.
When ~lang is present, the module named after ~lang supplies initial bindings for body of the module. In that case, a submodule body cannot refer directly to the bindings of the enclosing module, and no other module in the enclosing module can use the name id.
When ~early is present, or when ~lang is used without ~late or ~splice, then the submodule is defined before the rest of the enclosing module is expanded. The rest of the module can import the submodule using self!id, for example, or the submodule might be used from outside the enclosing module. In the latter case, the enclosing module need not be instantiated to use the submodule.
When ~late or ~splice is used with ~lang for a submodule, then the submodule is expanded only after the enclosing module, similar to use module without ~lang. The submodule can import from the enclosing module using parent, or it can import from sibling submodules using a module path such as parent!id.
Using ~splice without ~lang has no effect, but using it with ~lang means that multiple module definitions are combined, like when not using ~lang. When both ~splice and ~lang are used for a submodule name, then every declaration for that name must use ~splice and ~lang with the same module_path after ~lang.