Apologies on creating yet another modulary thread in parallel, but I don’t believe I have seen the approach I’ve been mulling over considered. I have been contemplating submodules not from an access scoping perspective, but from a packaging one. In other words rather than defining the ability to have a module contain modules, have multiple peer-level modules contained a library or executable. A module would effectively be a build target, and applications/libraries are composed of modules.
I’m not yet proposing any other features which would make this work conceptually differently than having one library per module today - I want to see if there is positive feedback around this first.
This approach has several advantages that I can think of:
1. Relatively simple model to explain
2. Additive proposal - if someone wishes to continue to make a framework or app with just a single module, the tools can work the same way they do today
3. Still encourages smaller modules, while today this would cause an explosion of included libraries
4. Smaller modules provide a tighter level of encapsulation, alleviating some of the pressure for access control levels between module-internal and private
5. Resolves existing startup performance issues of dynamic linking large numbers of libraries by allowing modules to be combined into fewer libraries.
6. Since modules are defined as build targets:
6.1 it is possible to model a filesystem-based grouping for modules using build tools
6.2 source in a module does not need any changes such as annotation to indicate which module it is part of
6.3 support isn’t modeled by the visual layout of an IDE, can be represented in a multi-target swift package manager file (SE-0146)
This approach also has two identified disadvantages in its current, simplistic form:
1. no inter-module access control yet proposed. This requires extra consideration with modules as a packaging concept, since modules would need to be bundled into the same binary unit
2. modules cannot have cyclic type dependencies (same as libraries today). My personal experience is that this leads to better code design and maintainability, but it can be more difficult when designing modules, or refactoring one module into many.
3. as an extension of the above, the extra constraints on making code into a module would limit the ability to use modules as a grouping/naming system for exposed API - dependencies would need to be structured for such a thing to work, which might require code changes
4. some submodule proposals may have allowed for a hierarchy of module names, e.g. Foundation and Foundation.Net <http://foundation.net/>. There is nothing yet in this proposal which would define how such a system would work.
5. I do not have enough knowledge of the functioning of the Swift compiler and build tools to know the impact of this approach.
6. Technically this does not preclude submodules as well, although I would suspect having both concepts would mean too much complexity.