The Babylonian tower principle states that programming languages still, and probably will ever fail to produce abstraction mechanisms suitable for large software modules.
Software is often modeled as a directed graph. Nodes in this graph are usually software modules, which are connected through composition/decomposition mechanisms. For example, in the imperative paradigm, modules are routines, which interact through invocation. In the object oriented paradigm, modules are classes, which interact through mechanisms such as inheritance, type composition, etc.
But, such a graph can be drawn at different levels of granularity. One can for example have a node for every (high level language) statement in the program, or even for every machine level instruction. A typical such portrayal of a program is the block diagram, in which nodes are blocks, a sequence of machine instructions which are always executed together.
Fine grain graphs of this sort are useful for obtaining a global picture of the program. Such graphs may comprise hundreds of thousands, even millions of nodes, and an even a greater number of edges. To be able to design, understand and reasnon about software, one needed a coarser grain description. A coarse grain graph is obtained from a finer grain graph by grouping together a number of nodes into a single node. For example, the control flow graph is obtained by grouping together all blocks which belong into a single routine, creating one node out of these.
Ideally, the process of coarsening a graph can continue until one obtains a simple graph, say one which can be drawn on a drawing sheet, giving a high level description of the software. The full software graph can then be obtained by successive refinements of this high level description. Further, in an ideal setting, each such refinement replaces a node with a graph which is small and simple enough to be understood without examining other subgraphs.
In these idealized setting, we obtain a hierarchical description of the software. At each level of the hierarchy we have a graph, obtained by refining the graph of the previous level. This graph could be divided into subgraphs, each traceable to a node in the preceding level.
One may even dream about a design process which starts at the high level graph, and continues to refine it until the final software product is obtained.
t was the hope of many language designers that the main abstraction mechanism used by the language would be used for this refinement coarsening process. For example, Pascal allows the definition of routines inside routines, Modula allows modules to be nested in each other, etc.
The Babylonian tower principle summarizes the observation that no one abstraction mechanism can serve the coarsening mechanisms needed at different levels of this idealized picture. Further, the principles states that state of the art programming languages still fail to offer abstraction mechanisms for the organization of higher level software modules.
In C++ for example, one finds the following mechanisms:
However, the language provides no mechanism for the organization of the many source files found in a typical large software project. It is the responsibility of the software designer to craft a discipline of organizing these just as the interaction of this organization with namespace mechanism. Note that the language support decreases in the higher abstraction levels. Files, e.g., offer only two encapsulation levels, and no support of genericity (that is one cannot design a generic module and encapsulate it in a compilation unit, which takes type parameters). Namespaces are further limited in that they offer no encapsulation levels.
The situation is not much different with PHP, in which we again see
Similarly, in Java, one finds the following mechanisms:
Java allows the Babylonian tower to rise a little higher, in that the language sets for the designer clear and concise rules on how compilation units are organized in packages.
Eclipse adds several more levels to the tower, including the ability to organize software, and most imortantly, Java software in
Still, we see the trend that the support of higher level mechanisms is not as rich as the lower level. For example, Java offers minimal language support for the grouping of classes in packages. This support includes two main features:
But, the richer repertoire of language tools available for classes, including inner classes, enums, annotations, genericity, constructors, static initializers, etc., do not reach the package level.
The bundling of several packages in a jar files offers even lesser support, which is limited to a declaration that a package found jar file is sealed in that it does not allow clients to add more classes to this package.
Similarly, the tool support of the higher mechanisms offered by Eclipse: projects, workings sets and work spaces is very basic. It is not easy to formulate constraints on the ways that subsystems thus organized can interact with each other.
The Babylonian tower thus predicts a collapse of the abstraction mechanisms at the fourth or the fifth level, at which, with the absence of a pre-meditated architectures, the software is expected to fail. In trying to keep the number of subcomponents of each software unit in the limits of seven plus minus one or two principle, one would expect software organizational failure when the system has about 104 - 105 atomic units.
The use of spartan programming allows one to make a more effective use of the available language mechanisms, whereby gaining a level or even two of the Babylonian software tower.