Jul 01 2005
What People Don’t Understand About Software
To celebrate Independence Day weekend, with all of its cold beer, grilled meat, fireworks, and patriotic remembrances, I offer the following list of fundamental ways in which most people misunderstand software:
Software is Machinery
It’s common for non-engineers to miss the most fundamental characteristic of software, because what comes out of the development pipeline isn’t “real” stuff. It’s just text, and files, and numbers in a database. Nevertheless, software is machinery. Real machinery, in the sense that it is comprised of individual parts or components, each of which has to be engineered to relate and interact properly to other parts, such that the whole machine functions according to its design. In fact you could view software as simulated machinery, but this distinction doesn’t offer any comfort. Is a simulation of a lawnmower less complex than a lawnmower? In fact it is more complex, since you can’t simply machine each part from some material and set it on a shelf, certain that when you pick it up again it will still work. In simulations the parts are… well, simulated. This implies that they can be defined and redefined. Anything that can be redefined can change.
Most machines, and thus most software systems, are closed-state devices: this is just a fancy way of saying that they are designed to do a certain thing, reliably, and don’t suddenly go off and develop new capabilities. Push the eject button, the tray comes out. Push it again, the tray goes back in. Continue doing this and the same thing happens over and over. A well-designed machine does not have failure conditions that send it off into realms of unknown behavior. In the real-world of metal and plastic you can be relatively certain that your machine will not fail because two parts suddenly decide to interact in an undefined way. Instead, assuming the basic design is correct, you are looking at problems that might arise from physical failure, wear and tear, outside tolerances, and the like. Conversely, in software we don’t suffer physical failure (hardware failure happens at a meta-level outside our application’s realm of responsibility - it’s more analogous to an automobile failing because the laws of physics suddenly stopped working), but instead have to deal with the mutability of our parts. Much of software engineering over the last three decades has been focused on finding better and more controllable ways to define and maintain parts.