loading...
Cover image for Book Review: The Mythical Man Month (1995)

Book Review: The Mythical Man Month (1995)

awwsmm profile image Andrew (he/him) Updated on ・9 min read

Note: all page numbers below are for the Kindle version of the book.

This book was absolutely painful at the start. The 20th anniversary edition (1995) hasn't updated any of the references (obviously) because it's a retrospective about what the author has learned in developing a large software project. Unfortunately for those of us living in the 21st Century, that software project was the development of IBM's OS/360. Get ready for exciting discussions of microfiche, "map lights" in cars, and more. "Structured programming" is introduced as "another important set of new ideas" (146). I took notes while reading this book and at one point, I wrote:

basically unreadable due to aging poorly

Here are a few quotes to illustrate my point.

"If a separate machine is needed, it is a rather peculiar thing--it need not be fast, but it needs at least a million bytes of main storage, a hundred million bytes of on-line disk, and terminals. Only alphanumeric terminals are needed, but they must go much faster than the 15 characters per second that characterizes typewriters." (132)

"What high-level language should one use for system programming? The only reasonable candidate today is PL/I." (138)

"I am convinced that interactive systems will never displace batch systems for many applications." (139)

One particularly egregious example is where the author recommends adding comments to the source code of a program, but not too much, because it could significantly increase the size of the program on the disk (177). (Which I guess is technically true but no longer an issue on modern computers.) The author also recommends using arrows instead of words to illustrate program flow:

I can hardly imagine a single piece of advice which would make a program less readable and more cluttered. So not everything in this book has aged well.

...that being said, once you've struggled through the first few chapters, the book really does have some good advice. I'll lay out the most useful themes I found here.

Creating Understandable Code is Hard, but Necessary

"A basic principle of data processing teaches the folly of trying to maintain independent files in synchronism" (171). The author recommends against separating documentation and code, instead promoting the idea that the source code file itself should contain prose explanation of that code. What he calls "self-documenting programs" we would today call "well-commented code". Make sure you explain any code which isn't self-explanatory.

"As a principal objective, we must attempt to minimize the burden of documentation, the burder neither we nor our predecessors have been able to bear successfully." (172)

To that end, the author recommends that we "use the parts of the program that have to be there anyway": use whitespace and brackets to format code, clarify scope, and so on. Give your variables, methods, and classes sensible, self-explanatory names. "Show, don't tell" makes reading -- and writing -- a much less painful process.

Don't reinvent the wheel. "Refer to standard literature to document basic algorithms whenever possible" (176), rather than "rolling your own". If you have to extract a single algorithm from a large package to avoid importing the entire package, do so. Just refer to the original source so you can find it later if necessary.

Don't be afraid to be too verbose. If a bit of code is unclear, write a single-line comment. If a section or algorithm needs explanation, write a paragraph: "use line comments or remark anything that is not obvious" (176). It is far better to be too explicit than to be too vague. Your future self, returning to those comments, will be thankful.

Programming is an Inherently Intellectual Challenge

One of the central theses of this book is that, once all of the incidental challenges of programming have been overcome or abstracted away with automatic memory and file management, expressive high-level languages, widely-available algorithms and data structures, and so on, what challenges are left for the programmer? What's left is simply expressing the problem to be solved in such a way that it can be interpreted by a machine. In other words:

"Representation is the essence of programming." (110)

In 2019, the most difficult part of programming is not learning syntax or managing resources or anything low-level, really. It's being able to completely and unambiguously express the problem you wish to solve, such that a machine can help you to arrive at a solution. Sure, collections and classes and lambdas may help you express the problem, maybe in a less error-prone or more comprehensive way, but they will not do your work for you. They are only tools. It is still up to you, as the programmer, to use those tools to create.

"We can write good or bad programs with any tool. Unless we teach people how to design, the languages matter very little." (221)

Software (Development) is Complex

I had a teacher in high school who always used to say "repetition is your friend". What she meant was that humans need to see concepts and ideas repeated, sometimes in different ways, in order to fully understand and absorb them. Machines don't need this. If you write a function or a class definition once, you don't need to write it again.

"Software entities are more complex for their size than perhaps any other human construct, because no two parts are alike (at least above the statement level). If they are, we make the two similar parts into one, a subroutine..." (183)

The DRY (Don't Repeat Yourself) mantra espoused by many software developers promotes the idea that regularly-used chunks of code should be encapsulated in methods which are easily called, debugged, and documented, rather than copying and pasting those lines over and over throughout your code. Code organised in this way will never repeat anything larger than a statement, or a single line. Information theory says that this kind of code is maximally entropic. By repeating as little code as possible, we maximise the "information density" of that code.

This means that "good" code is, by definition, as complex as it can possibly be. I use the word "complex" here not to mean "confusing" or "obfuscated", or to mean that the code has a difficult-to-understand syntax. I mean that not a single chunk of code is repeated, everything is unique, everything carries new and different information that what was presented before. Crafting good software necessarily means crafting complex software:

"...a scaling-up of a software entity is not merely a repetition of the same elements in larger size; 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." (184)

Achieving a significant increase in programmer efficiency, then, is a matter of making it easier to express complex relationships and objects in fewer lines of code (272). Not better or faster editors, not new syntax or frameworks or languages per se, but the ability to express higher-level concepts in those frameworks and languages in an easier, less error-prone way. That is what will increase programmer efficiency in the future.

Maintaining Conceptual Integrity

Software projects, like teams of people, increase supralinearly in complexity as they increase in size. Doubling the size of a program increases by a factor much greater than 2 the number of ways in which that API can be used, abused, and connected to other packages. Similarly, a team of 4 people has 9 possible communications channels among its members (unique sub-teams of 2 or more people). A team of 8 has 49. A team of 16, 225. Complexity increases quadratically.

When a project is built by a single person, maintaining conceptual integrity is relatively easy. Only one person needs to make sure the code is formatted uniformly, documentation uses the same verbiage, the UI is consistent, and so on. When a project team is as small as two people, communication is imperative to maintain this consistency across the project. So communication among teams is essential to maintaining conceptual integrity.

Early in the book, the author recommends a radical re-design of a development team, for projects with only a handful of people -- the surgeon's team. In this project structure, only one person is responsible for the conceptual vision of the project. This person, "the surgeon", does the structural and design work, while another skilled programmer helps by building secondary bits of code: lower-level subroutines, backend data management frameworks, and so on. The surgeon is free to focus on her "vision" for the project, while others support and aid the surgeon.

Of couse, this won't work for most teams (in spite of the author's recommendation), especially large ones, where one "visionary" would not be able to handle all the work required of them. So as much as possible, design decisions should be documented and explained, so that everyone involved in the project can refer to them. As I said earlier, it's always better to be overly explicit than overly vague.

"Preparing each document of this small set focuses thought and crystallizes discussion. The act of writing requires hundreds of mini-decisions, and it is the existence of these that distinguish clear, exact policies from fuzzy ones." (240)

But it is not necessary for everyone to know everything about the project. In fact, it's preferable if the Law of Demeter (or, "principle of least knowledge") is followed as closely as possible:

"...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 only see the interfaces." (236)

In other words, you don't need to know how a subroutine works, just that it does. You should focus on the inputs to and outputs from a function, not what it does internally. This increases reusability and modularity of code.

Grow, Don't Build

Although the traditional "waterfall" software development method is assumed throughout the book, the author acknowledges this in the 20th Anniversary edition, and more or less apologizes for it (265). Times change, and software development has evolved probably more drastically than any other industry in the history of civilization, all in less than 80 years.

With the benefit of hindsight, the author now recommends a more Agile-like framework: build an end-to-end system that does nothing first -- it only makes the correct subroutine calls in the correct order. Then, build out the subroutines one at a time, test, rinse, repeat. In this way, you will always have a working system (albeit with limited functionality) which can constantly be tested by users (202).

"The morale effects are startling. Enthusiasm jumps when there is a running system, even a simple one." (202)

In addition to "growing" software, we should also grow great software developers. Few companies nowadays are in the habit of putting in the effort to start with brand-new developers and growing them into great, experienced ones. The Mythical Man-Month offers a few tips for this process:

"Systematically identify the top designers as early as possible. The best are often not the most experienced. Assign a career mentor to be responsible for the development of the prospect, and keep a careful career file. Devise and maintain a career development plan... including carefully selected apprenticeships with top designers, episodes of advanced formal education, and short courses, all interspersed with solo design and technical leadership assignments." (204)

As a manager, it is not so much your duty to develop top talent as it is your duty to allow it to develop on its own (276). Provide space, facilitate team meals and meetings, take care of all the mundane aspects of the work, so that your star developers can get on with the work of developing. But most importantly, avoid micromanagement. Allow employees to take control of their own projects, set their own deadlines, and manage their own time and resources as much as possible -- you'll be surprised at the results:

"I can't emphasize enough the importance of empowerment." (279)

Summary

I was extremely skeptical at first, but after struggling through the first 20% or so, the rest of this book was full of great advice. I don't recommend it for early-career developers, as it seems to be geared mainly toward team leaders. Tips on managing teams of people, maintaining development projects across those teams, and empowering employees to perform at their peak can be found on nearly every page of this book. But maybe skip the first few chapters.

Posted on Jun 16 '19 by:

awwsmm profile

Andrew (he/him)

@awwsmm

Got a Ph.D. looking for dark matter, but not finding any. Now I code full-time. Je parle un peu français. dogs > cats

Discussion

markdown guide
 

I read the paperback version of this book (20th anniversary edition 1995) a few years back, when I was getting deeper into being the core Solaris gatekeeper and figuring out how to improve our back-end tools.

At that time Solaris org was ~2500 people and we had many many decades of experience at different methods of software project planning, implementation and delivery.

The core message of TMM which has stuck with me over the years is that the project team size at which you need to get a project/program manager and somebody whose primary focus is tooling is actually quite small. That is exactly what we did with Solaris - though we did rotate people through those roles so that both the benefits and the pain were shared throughout. As a worldwide organisation this was perhaps even more important than in a geographically disparate but still same-country team.

Another core value we had was that everybody was empowered to not only suggest improvements in (or log bugs against) the common build tools, but to also go and fix those tools themselves. Apart from providing a good way for new staff to learn about our dev methods and approaches, it was just a core part of the corporate culture.

 

That's the one bit of advice that I wasn't so sure about from TMM -- that even groups as small as four people should have an "architect" and a "tools designer". But I don't have much experience in the industry, so I'll have to take your word for it!

 

My experience is that when you've got fewer than 10 people in the team, many of those roles can be combined - or even just shared around. Though I'd make sure that there's just one architect. If you've got a small team you have to work with and around each other, and I suggest that in that sort of environment everybody should be tasked with process as well as code.

That could get a little interesting if you have people of wildly differing skill levels, but the more senior members should be taking the lead on pulling the juniors up to their level. If you're in a team that small and the seniors aren't doing that, then they're not pulling their weight and you need to find a way to get them to do so.

 

basically unreadable due to aging poorly

Glad you eventually got some value out of it... as someone interested in the history of the field, I found the references to older tech to be a nice bonus back when I read it.

Much of the rest is timeless, though IIRC it applies more readily to very large teams writing very large projects from scratch while maintaining large typewritten manuals, and all of it without the benefit of VCS.

So much of what Brooks advocates for (and I don't mean to imply that he was the lone voice) has become conventional -- tracking milestones, avoiding complexity, prototyping, versioning, standardizing tools, separating spec from implementation -- that I doubt many folks reading MMM today would be surprised by any of the takeaways. But I found it interesting both as a primary source and as a window into a time when those practices couldn't be gotten for free or taken for granted.

Peopleware is another classic in this vein, but unlike MMM, its lessons (despite empirical proof) are often ignored.

And though I haven't yet, I'm looking forward to reading Patterns of Software at some point.

What he calls "self-documenting programs" we would today call "well-commented code".

I don't follow. Self-documenting code is code that reduces the need for explanation, including comments. As you mentioned, things like "show, don't tell" and "use the parts of the program that have to be there anyway" are what you want -- more specifically, they're preferable to comments, and part of an alternative.

 

I think you're right. Most of what is discussed in TMM is taken for granted nowadays -- lots of disk space so comments can be interleaved with source code, distributed version control systems, better communication across teams, and more.

Brooks actually recommends Peopleware near the end of TMM, so I'll definitely have to check it out.

Finally, with regards to your last comment, I think it's a matter of usage. From what I can gather from Brooks' writing in TMM, he defines "self-documenting programs" as programs which have the documentation included with the source code, as opposed to typed up and printed in a separate manual somewhere. I think I agree with your more modern definition of "self-documenting code", in that variable names, function names, etc. should be self-explanatory, and therefore not need much documentation or commenting at all. I think it's just a shift in the connotation since 1975.

 

Oops, I misread you & thought you were advocating for a shift in the recommendation. But that makes perfect sense.

 

Well certain concepts like

"There's no silver bullet"
"Adding people to a late project makes the project later"
"The second system effect"

Are well known lessons today that Brooks introduced. They are well known these days.
This book started a discussion that continues till this day.

I second Peopleware as an important book who's lessons we'd probably learn from if we went back to them. For example, the concept that come developers were 10x more productive than others was more due to environment than skill or experience. A lesson that is often forgotten today.

 

I’ve heard some of the high level points of this book, and wanted to get around to reading it but was looking for a post just like this to actually get started with.

Very much appreciated!