Here is an attempt to explain Dule to a literate ML programmer, (that emerged in a discussion with Mariusz Rak). I hope, finally the link between lack of exponential objects and one-name one-meaning principle is made clear. Executive summary: 1. ML functors are OK for keeping modules really abstract. 2. However, you have to write lots of sharing equations. 3. Type abbreviation, sharing equations, etc., fail in practice. 4. Instead of functor application, use module categorical composition! 5. With no exponential objects, every module is consumed when applied. 6. In the ensuing one-name one-meaning module system, sharing is trivial. 7. Profit! The real thing: 1. Parameterization (as in SML or OCaml) of a module is an accurate way of conveying the notion that the module is independent from the implementation details of other modules. The compiler itself assures that the module can only refer to the interfaces of parameters, and so the module cannot assume a particular implementation of types defined in the parameters. 2. Parameterization with totally abstract interfaces does not suffice for modular programming, due to very frequent and interacting cases, where the programmer actually has to break through the abstraction barrier. As a rule, the programmer needs to known the identity of most of the types coming from parameters, or more precisely, their equality to the types from other parameters (type sharing). Otherwise, the programmer cannot compose functions from different parameters. 3. Existing methodologies for managing type sharing for parameterized modules do not scale. In SML and OCaml the programmer uses various kinds of sharing specifications accompanying the parameter interfaces. In large programs with very fine-grained modularization, sharing specifications are longer than the code of the implementation of a module. Consequently, the module headers are hard to debug and they obscure any non-trivial modular phenomena (e.g., multiple interfaces for a single module or a type that is totally abstract in all but a few modules that use it). 4. Dule is based on a different mechanism for expressing autonomy of modules. Instead of a parameterized module, that is a function from a cartesian product of sets of modules into a set of modules, we take a categorical morphism from a product of objects to an object. This is only a mild generalization, but here comes the difference: instead of the (lambda-calculus inspired) powerful set of operations for applying a function (a module) to its arguments, Dule is based on composition of categorical morphisms and the set of product operations needed to gather arguments together before composition. 5. Categorical composition is obviously not commutative, but in the absence of exponential object, its operands differ also in their relation to outside "environment". Product operations allow the operand corresponding to function arguments to be expanded (refer to the environment) even when already engaged in the composition, while the operand corresponding to the function body has all its "expansion slots" filled with the arguments. Thus, once a module is composed with its arguments, it is fixed and "consumed"; it cannot be cloned (via product operations) to be composed with other arguments, nor can it be extended with any modules from the environment, which could be cloned and used elsewhere. On the other hand, the result of the composition can be cloned and used as arguments in many outer compositions (so arguments are not consumed). 6. Such immutable, one-time module composition naturally leads to a module system with one-name one-meaning property. Dule is such a module system, created by augmenting the simple categorical model with module identifiers as labels of finite products, a name-oriented sublanguage for defining module interfaces and a lot of syntactic sugar. Sharing specifications are unneeded in Dule, because modules (and so types) are assumed equal, if only their names are equal. In the rare cases of an unintentional name clash, modules can be trivially renamed using the product operations, with convenient syntactic sugar for both modules and interfaces. Equally rare cases of sharing violation seldom involve more than three nodes of the module hierarchy. 7. Conventional parameterized modules are still useful in their role as libraries or generic modules, e.g. a module of sets or a module of maps. The categorical approach requires an exponential object to capture such functionality. However, an exponential object, even if it would exist in the categories in question, clashes with the simplicity of modular interdependencies. Dule has parameterized modules as a separate, non-categorical language extension that uses the module renaming idioms to locally disrupt the one-name one-meaning principle.