Modularity, Abstraction, and Modelling
Whether proving a theorem by creating up from lemmas to simple basic theorems to more accurate results, or designing a circuit by creating up from elements to modules to complex processors, or designing a software system by making up from generic functions to classes to class libraries, humans operates with complexity by exploiting the power of modularity and abstraction. Without such functions, a single person could be overwhelmed by the complexity of a machine, as there is only so much information that a one person can consciously manage at a time.
Modularity is the concept of creating components that may be re-used; and abstraction is the concept that after preparing a module, most of the information of the module construction may be ignored and a simpler description given for module communication.
Given simple modules, one may move up a level of abstraction and create a new module by having together various previously-create modules, thinking only of their abstract information, and not their implementations. And, of course, this function may be repeated over several stages. This function provides one the ability to construct machine with complexity far beyond what would be possible if it were important to understand every element in detail.
Any module may be defined in a large number of types. We might illustrate the circuitry in a digital watch in parts of how it works as a clock and a stopwatch, or in terms of currents and voltages within the circuit, or in terms of the heat given at different types of the circuitry. Each of these is a different kind of model of the watch. Different models will be important for different tasks: there is no single correct operation. Rather, every model exposes different dimensions of the machine, allowing us to explore different aspects of the design space of a machine, and to sell off different factors in the performance of a machine.