This book review originally posted at nicholascloud.com.
The Mythical Man-Month is one of those books that is, well, mythical in the circles to which it pertains -- that is, the software engineering and computer science fields. It is mythical because many people have heard of it, most agree that it is "classic", but not many remember exactly why. Perhaps they have never read it, only absorbed its ideas through hearsay. Or perhaps they did read it, but so long ago that its principles have been taken only in the tide of time.
Either way, I have finally finished the book in what I consider to be an unreasonable amount of time. It's not overly long, or overly verbose, but I have a bad habit reading a little from a lot of books at the same time, which means I don't finish a book for a while. I took notes as I went so that hopefully time will be more gracious to my mind when someone asks me, in the years to come, if I've read Frederick Brooks.
Widely considered the central theme of the book, Brooks's Law, in summary, is that adding programmers to a late software project will not make it go faster, but rather slower. This was a pattern Brooks saw during his years as a manager in larger companies that needed many engineers to write software either for internal use, or eventually for sale as products. Managers assumed that the central problem of software development -- why projects did not finish on time or on budget -- was a mechanical one that could be resolved with mechanical solutions. Maybe there just wasn't enough manpower. Or maybe the tooling was inferior, and retarded progress. Or maybe the wrong language had been chosen for the task. While all of these things can, and do, affect software engineering endeavors, Brooks's major insight was that they were the accidents of software engineering, and not its essence; and that the essence is what causes projects to fail.
The essence of "systems programming" (as Brooks called it) is one of complexity -- an irreducible complexity1 -- that of itself cannot be fixed by mechanical solutions. This complexity arises from the fact that software development is a creative, human process. The engineer must, to write a program, conceptualize the problem space correctly and then use the tools at his disposal to create a solution. As projects grow, engineers are added, the consequence of which, as Brooks keenly observed, tends to make the project slower because it increases the number of communication pathways among team members (with every addition), and the conceptual foundation of the project becomes spread among many minds, in ways that are often fragmented and incorrect. This, Brooks argues, is the core problem, and the solution to the problem is to adapt to it rather than try to conquer it.
"Complexity is the business we are in, and complexity is what limits us."
How does one adapt to the problem of conceptual complexity in software engineering? Brooks proposed a number of solutions.
Brooks proposed that the conceptual integrity of a project -- the core ideas about what the problems are and the models used to represent those problems -- are of primary importance and must be safeguarded. The most efficient way to ensure this happens is to reduce the responsibility of that integrity to one, or at most, a couple of individuals, that will be responsible for enforcing that conceptual integrity by vetting the work of other team members on the project. They become the source of conceptual truth.
Because complexity scales with the number of communication pathways in a team, Brooks proposed that "surgical teams" be used in most software projects. These teams will be composed of the conceptual guardian(s) (the "surgeon"), and as few people as possible to get the work done. These teams are part of an organization as a whole, however, and there is always a management structure with which they must integrate. The key to good management, according to Brooks, is to realize that management is about action and communication. The person at the top should rely on his subordinate program managers to take action when needed, and he should give them the authority to do so. He should never, ever demand action when reviewing a general status report, however, because this will debilitate his program managers, and move the decision making power further from the decisions that needs to be made. Project managers should be concerned almost exclusively with managing the lines of communication in the team, and not with making decisions at all. The whole process of pushing decision making "down" to the program manager is effective because it gives program managers a stake in the total authority of the company, and therefore preserves the total authority of the company.
"The purpose of organization is to reduce the amount of communication and coordination necessary..."
"...the center gains in real authority by delegating power, and the organization as a whole is happier and more prosperous."
Complexity can be addressed in the code itself by reducing the mental burden a programmer has to carry while implementing code that has conceptual integrity. In the first edition of Brook's book, he insisted that all programmers on a team be familiar with all modules (or entities) within a software project. In Brooks's mind, this was a good way to safeguard the integrity of the system, because everyone would have a working understanding of all code. In a subsequent edition of the book, he backtracked on this position, because it essentially suffered from the mental equivalent of the communication problem. Code changes over time; no programmer ever has a complete and accurate understanding of system because it is not static. Brooks eventually came around to a view promoted by Canadian engineer David Parnas:
"[David] Parnas argues strongly that the goal of everyone seeing everything is totally wrong; parts should be encapsulated so that no one needs to or is allowed to see the internals of any parts other than his own, but should see only the interfaces... [I initially proposed that] Parnas's proposal is a recipe for disaster [but] I have been quite convinced otherwise by Parnas, and totally changed my mind."
Information hiding, or encapsulation, allows a programmer to "use" or take advantage of, code, without having to know how it works internally, only how to ask it for something. The mental footprint of understanding an interface (the way to ask code for something) is orders of magnitude smaller than the mental footprint required to understand the implementation behind the interface. And interfaces don't change nearly as often as implementations (in a well-designed system).
Side-effects (changes created by a piece of code that change things beyond that code, or even system), likewise, should all be identified, well understood, and encapsulated (or eliminated) to reduce the mental burden of worrying about tangential consequences to implementations, which are often causes for bugs, and project delay.
Documentation is central to adapting to complexity. Documenting decisions made in a software project is part of fostering the creative process itself:
"...writing the decisions down is essential. Only when one writes do the gaps appear and the inconsistencies protrude. The act of writing turns out to require hundreds of mini-decisions, and it is the existence of these that distinguishes clear, exact policies from fuzzy ones."
Documentation need not be overly verbose, however; although overly verbose documentation is better than no documentation, Brooks believed. And the documentation regarding technical decisions -- design and implementation -- should be as close to the code itself as possible (even within the same code files) to ensure the documentation will be maintained and updated as the code itself changes. The goal of documentation should be twofold: 1) to create an overview of the particular system concern the documentation addresses, and 2) to identify the purpose (the why) of the decisions made in regard to that concern. Documentation is not only for other programmers to read; it is often to benefit the original author as well.
"Even for the most private of programs, prose documentation is necessary, for memory will fail the user-author."
There are many more things I could say about Mythical Man-Month. More subtle insights, longer expositions on points articulated above. But these points are the ones that stuck with me most, the ones I felt were immediately relevant to my own work and career. Mythical Man-Month is one part history, one part knowledge, and one part wisdom. It lets us know that great minds in past struggled with, devised solutions to, and retracted and revised solutions to, the problems that make programming a struggle of genuine creativity.
This last quote is taken from a critique of Brooks, one that he found to be excellent, and expresses the same conclusion (albeit maybe a bit more pessimistic) at which Brooks himself arrived: the central problem of software is complexity, not tools or processes, and that will never change.
"Turski, in his excellent response paper [to No Silver Bullet] at the IFIP Conference, said eloquently: 'Of all misguided scientific endeavors, none are more pathetic than the search for the philosopher's stone, a substance supposed to change base metals into gold. The supreme object of alchemy, ardently pursued by generations of researchers generously funded by secular and spiritual rulers, is an undiluted extract of wishful thinking, of the common assumption that things are as we would like them to be. It is a very human belief. It takes a lot of effort to accept the existence of insoluble problems. The wish to see a way out, against all odds, even when it is proven that it does not exist, is very, very strong. And most of us have a lot of sympathy for those courageous souls who try to achieve the impossible. And so it continues. Dissertations on squaring a circle are being written. Lotions to restore lost hair are concocted and sell well. Methods to improve software productivity are hatched and sell very well. All too often we are inclined to follow our own optimism (or exploit the hopes of our sponsors). All too often we are willing to disregard the voice of reason and heed the siren calls of panacea pushers.'"
- Not to be confused with the same term used by some creationists to defend their particular ideas about the origin of the universe.