First, one must observe that the anomaly is not that software progress is so slow, but that computer
hardware progress is so fast. No other technology since civilization began has seen six orders of
magnitude in performance price gain in 30 years. In no other technology can one choose to take the gain
in either improved performance or in reduced costs. These gains flow from the transformation of
computer manufacture from an assembly industry into a process industry.
I believe the hard part of building software to be the specification, design, and testing of this conceptual
construct, not the labor of representing it and testing the fidelity of the representation. We still make
syntax errors, to be sure; but they are fuzz compared with the conceptual errors in most systems.
Likewise, a scaling-up of a software entity is not merely a repetition of the same elements in larger sizes,
it is necessarily an increase in the number of different elements. In most cases, the elements interact with
each other in some nonlinear fashion, and the complexity of the whole increases much more than
linearly.
Many of the classic problems of developing software products derive from this essential complexity and
its nonlinear increases with size.
From the complexity comes the difficulty of communication among
team members, which leads to product flaws, cost overruns, schedule delays. From the complexity
comes the difficulty of enumerating, much less understanding, all the possible states of the program, and
from that comes the unreliability. From complexity of function comes the difficulty of invoking
function, which makes programs hard to use. From complexity of structure comes the difficulty of
extending programs to new functions without creating side effects. From complexity of structure come
the unvisualized states that constitute security trapdoors.
Conformity. Software people are not alone in facing complexity. Physics deals with terribly complex
objects even at the "fundamental" particle level.
The physicist labors on, however, in a firm faith that
there are unifying principles to be found, whether in quarks or in unifiedfield theories. Einstein argued
that there must be simplified explanations of nature, because God is not capricious or arbitrary.
No such faith comforts the software engineer. Much of the complexity that he must master is arbitrary
complexity, forced without rhyme or reason by the many human institutions and systems to which his
interfaces must conform.
These differ from interface to interface, and from time to time, not because of
necessity but only because they were designed by different people, rather than by God.
Changeability. The software entity is constantly subject to pressures for change. Of course, so are
buildings, cars, computers.
But manufactured things are infrequently changed after manufacture; they
are superseded by later models, or essential changes are incorporated into later-serial-number copies of
the same basic design. Call-backs of automobiles are really quite infrequent; field changes of computers
somewhat less so. Both are much less frequent than modifications to fielded software.
In short, the software product is embedded in a cultural matrix of applications, users, laws, and machine
vehicles. These all change continually, and their changes inexorably force change upon the software
product.
Invisibility. Software is invisible and unvisualizable. Geometric abstractions are powerful tools. The
floor plan of a building helps both architect and client evaluate spaces, traffic flows, views.
Contradictions and omissions become obvious. Scale drawings of mechanical parts and stick-figure
models of molecules, although abstractions, serve the same purpose. A geometric reality is captured in a
geometric abstraction.
The reality of software is not inherently embedded in space.
Hence, it has no ready geometric
representation in the way that land has maps, silicon chips have diagrams, computers have connectivity
schematics. As soon as we attempt to diagram software structure, we find it to constitute not one, but
several, general directed graphs superimposed one upon another. The several graphs may represent the
flow of control, the flow of data, patterns of dependency, time sequence, name-space relationships.
These graphs are usually not even planar, much less hierarchical. Indeed, one of the ways of establishing
conceptual control over such structure is to enforce link cutting until one or more of the graphs becomes
hierarchical.
In spite of progress in restricting and simplifying the structures of software, they remain inherently
unvisualizable, and thus do not permit the mind to use some of its most powerful conceptual tools.
This
lack not only impedes the process of design within one mind, it severely hinders communication among
minds.