Introduction
Modular design and modular programming support the decomposition of a
program into several software units, also called modules,
which can be developed largely independently. A module can be
compiled separately from the other modules comprising the program.
Consequently, the developer of a program that uses a module does not
need access to the source code of the module: the compiled code of the
module is enough for building an executable program. However, the
programmer must know the interface of the modules used, that is,
which values, functions, types, exceptions, or even sub-modules are
provided by the module, under which names, and with which types.
Explicitly writing down the interface of a module hides the details of
its implementation from the programs that use this module. All these
programs know about the module are the names and types of exported
definitions; their exact implementations are not known. Thus, the
maintainer of the module has considerable flexibility in evolving the
module implementation: as long as the interface is unchanged and the
semantics are preserved, users of the module will not notice the
change in implementation. This can greatly facilitate the maintenance
and evolution of large programs. Like local declarations, a module
interface also supports hiding parts of the implementation that the
module designer does not wish to publicize. An important application
of this hiding mechanism is the implementation of
abstract data types.
Finally, advanced module systems such as that of Objective CAML support the
definition of parameterized modules, also called
generics. These are modules that take other modules as
parameters, thus increasing opportunities for code reuse.