Summary of No Silver Bullet by Fred Brooks
Werewolves are frightening, because they suddenly transform from familiar (a human) to threatening (a wolf). Software projects are like that. They seem innocent and straightforward, and things are going well, but they can become a monster of delays, cost overruns, and a flawed product delivered after all this. In folklore, werewolves are impervious to most weapons, except silver bullets. Software managers likewise search for a silver bullet, but:
There’s no single technology or management technique which delivers a 10x improvement in productivity, reliability or simplicity of software. ← summary of the paper in one sentence
Accepting that there’s no magic helps us find realistic solutions, just as medicine advanced only after we accepted that diseases are not caused by demons.
Software construction involves:
Essential complexity, which is the complexity that users are paying for. You could simplify Photoshop by getting rid of 80% of its features, but that’s not what its users want.
Incidental complexity, which does not add value to users. Example: your continuous deployment pipeline breaks.
In order to get a 10x improvement, unless incidental complexity is 90% of the time, even if you shrink it to zero, it won’t give you the 10x improvement. Which means we need to tackle essential complexity.
Essential complexity arises from:
Complexity
Conformity
Changeability
Invisibility.
Problem 1: Complexity
In software, every component we build is unique. If it’s not, we reuse an existing component.
A big software project does not have the same components as a small program but scaled up, just as a train is not a bus with bigger wheels. A big project has different components, and more of them, which interact non-linearly, resulting in a non-linear increase in complexity.
Complexity causes a whole set of problems: unreliability and security problems, because no person or team as a whole can understand every state it can get into. Communication and management breakdowns, which cause product flaws, cost overruns and delays. Complex software is also hard to extend.
Over the past few centuries, science made a lot of progress by constructing simplified models of complex phenomena. This works because a molecule in a gas is not unique from other molecules, so you can treat them statistically, such as by saying that a certain percentage of molecules are in an excited state. Unfortunately, every component in a software project is unique. Further, while a particle may behave in complex ways, it obeys fundamental laws. Unfortunately, components in software are man-made and behave arbitrarily.
Problem 2: Conformity
Software needs to conform to interfaces exposed by other software, and human and social expectations, which impose complexity.
Problem 3: Changeability
Cars and buildings don’t change much after launch. Instead, they’re replaced in their entirety by a newer model.
But people ask for software changes, partly because software is malleable. Partly because once it’s successful, people start using it for new use cases.
Problem 4: Invisibility
Many fields have a visual representation, like a floor plan for a building, or a map for land. These help point out omissions and contradictions, like a room that has no doors to enter it.
Unfortunately, software is not representable in a visual form. You’ll need a multidimensional graph to model it, and even then you could model different things like the flow of control, flow of data, or dependencies. Or flow of time. There are many ways you can diagram a software system, and none of them give you the complete picture. If you try, you’ll end up with something so complex no one can understand.
Visualisation is a powerful tool of the mind, and software is un-visualisable, hindering both understanding and communication.
Proposed solutions that don’t work
AI doesn’t work, partly because AI techniques from one field (like image-processing) don’t transfer to other fields.
Program verification doesn’t work because it’s so much work that only a few substantial programs have been verified. Even if it could work, it proves only that the program meets the spec, not that the spec is correct. Much of the work in programming is in coming up with a correct and complete spec, and much of the debugging is debugging the spec.
Proposed solutions that are promising
Reuse what has been built by others. Even if a component costs $100,000, that’s just one engineer’s salary for a year, and delivery is immediate. Such components also tend to be better documented than in-house components. Sharing the cost of development even among a few users drastically reduces the cost (1/n).
Prototype rapidly: users don’t know what they want, completely, correctly and precisely, so they can’t tell developers. Instead, developers should extract and refine requirements iteratively. If you get this wrong, you’re building the wrong product, and you can’t recover. Clients that specify their requirements, solicit bids from agencies, and then try to get it built, are doing it wrong.
Grow software organically, adding more and more function as the software is used and tested, always having working software. This speeds development and boosts morale.
Develop design skills. There’s an order of magnitude difference between software built by great and average designers. Software built by one or a few designers works better than those built by committee.