In an ideal world, Unix programmers would craft only small,
perfect gems of software, each minimal, each elegant, each
perfect. But one of the unfortunate things about reality is that it
often poses complex problems that demand complex solutions. You can't
control a jetliner with an elegant ten-line procedure. There are too
many pieces of equipment, too many channels and interfaces, too many
different processors — too many different subsystems defined by
independently operating human beings who often don't agree even on
fundamental conventions. Even if you are successful at making all the
individual software parts of an avionics system elegant, integration
is likely to produce a large, complex, and grubby body of code with
(one hopes) the single virtue that it will actually
work
.
Jetliners have essential complexity.
There is a rather sharp point past which it's not possible to trade
away features for simplicity, because the plane has to stay in the air.
Because of that very fact, avionics control systems do not tend to
spawn religious wars about complexity — and Unix programmers
tend to stay away from them.
Jetliners are certainly not immune from system failures due to
overcomplexity. But the design issues are easier to discern and think
about in software for which the requirements are more flexible, in
which it is easy to trade off between anticipated features and
complexity. (Here, and in the rest of this chapter, we will use
‘feature’ in a very general sense that includes things
like performance gains or overall degree of interface polish.)
When we fail to distinguish between optional and accidental
complexity, design debates become seriously confused. Questions about
what a project's objectives are get confused with questions about the
aesthetics of simplicity, and whether people have been sufficiently
clever.