Modules express the large grain structure of programs; as with procedures in the previous chapter, the motivation is to make programs easier to understand, and hence to maintain, especially large programs. Modules provide a larger grain structure than procedures, since modules can contain procedures.
The Y2K problem is a good example of the "experience" mentioned on page 225, that "actions and operations need to be considered together with the data they work on." More than just "considered together," it is often helpful if they are placed inside the same module, with the data representation hidden. If this had been done for dates in legacy programs, the Y2K problem would have been trivial to solve, requiring only a few lines of code to be revised in the date module. On the other hand, compiler technology for inlining code (mentioned on page 247) was not available when most legacy programs were written, so there would have been a significant overhead for the many calls of the simple procedures that manipulate dates (such as for computing elapsed time, or equality).
The kind of modules found in Ada, C++, ML, and Modula-3 have their origin in theoretical work by Goguen on abstract data types and general systems, and on the language designs for Clear (with Burstall) and OBJ. Despite what Sethi says on page 229, modules also have some advantages over classes, in that they can encapsulate more than one type, whereas a class encapsulates exactly one type. Also, contrary to page 244, ML-style polymorphic types are quite different from C++ templates, which are actually closer to parameterized modules than they are to parameterized types. The original syntax for a module parameterized P in Clear (in joint work with Rod Burstall from 1976) was
The notion of data invariant (page 218) can be useful for proving properties of modules that encapsulate states. However, this name is not always appropriate; for example, the internal state of a semaphor (or monitor) module in an operating system is a flag used to control processes; properties of such flags are often important for the correctness of concurrent programs, but it is hard to think of them as "data".