14.7 unit versus module

As a form for modularity, unit complements module:

The lambda and class forms, among others, also allow parameterization of code with respect to values that are chosen later. In principle, any of those could be implemented in terms of any of the others. In practice, each form offers certain conveniences—such as allowing overriding of methods or especially simple application to values—that make them suitable for different purposes.

The module form is more fundamental than the others, in a sense. After all, a program fragment cannot reliably refer to a lambda, class, or unit form without the namespace management provided by module. At the same time, because namespace management is closely related to separate expansion and compilation, module boundaries end up as separate-compilation boundaries in a way that prohibits mutual dependencies among fragments. For similar reasons, module does not separate interface from implementation.

Use unit when module by itself almost works, but when separately compiled pieces must refer to each other, or when you want a stronger separation between interface (i.e., the parts that need to be known at expansion and compilation time) and implementation (i.e., the run-time parts). More generally, use unit when you need to parameterize code over functions, datatypes, and classes, and when the parameterized code itself provides definitions to be linked with other parameterized code.