Insights and questions from the original waterfall paper

Monday, December 11, 2023

The waterfall model is probably the most reviled methodology in software engineering. This methodology was first described in a 1970 paper by Dr. Winston Royce. This paper didn't call it waterfall, nor did it endorse the technique, and the paper contains a lot of good insights and raises some interesting questions. Let's take a look at some of those.

Essential steps of software development

Royce says there are two essential steps in all programming: analysis and coding. It's not defined what goes into analysis, but I think we can safely assume it includes thinking about the problem and how to solve it. I think it's pretty clear that these steps are always involved. For extremely small programs, maybe they're all you need, though you probably don't do them serially.

The other steps involved for larger programs are requirements, program design, testing, and operations.

One interesting thing here is that I think these are all done at all sizes of software, they're just not done explicitly and separately. Let's say you write a small program, like a solution to an Advent of Code problem. For this, you need to get the requirements from the problem description, do some analysis on it, design your program, write it up, test it, and then run it for the answer. But these flow together, and code/test/operate get lumped together, and requirements/analysis/design get lumped together—with both of those groups getting intermingled as well. They're not done serially one after another, but each is done at some point.

What are really the essential steps of software development? I'm not sure. I think the breakdown of activities he mentions in this paper is interesting and a nice way to think about the activities we engage in, and I can't really go further than that at the moment.

What is the role of management?

One point that Royce makes is... interesting:

The prime function of management is to sell these concepts [of testing, documentation, analysis, etc.] to both groups [developers and customers] and then enforce compliance on the part of development personnel.

He continues this later on, too:

The first rule of managing software development is ruthless enforcement of documentation requirements.

And this quote is followed by saying that if documentation isn't good enough, then replace management.

So, this makes clear Royce's view on management's role: strictly enforcing rules and proper development practice. If they don't ruthlessly enforce documentation processes, then they'll be fired. And they need to make sure developers do their testing and analysis and design, too.

I mean... I don't know what it was like in the 70s, a couple of decades before my time. So this could be the right take at the time. In the present day, it seems very antithetical to what I've experienced in the teams I work on.

On the teams I'm on, what I've generally seen is:

  • Engineers advocate for testing, for requirements, for explicit design time
  • Management pushes for less of these in some instances

This is the opposite of what he says happens! I'll give him this, though: developers sure do like skipping documentation, and customers do want to avoid paying for these things.

For me, the role of management is not as ruthless enforcer but as facilitator. Software engineering is more mature as a field than it was 53 years ago, and we have some established best practices. As practitioners, we take pride in our work and we do push for testing, analysis, all the good stuff. And the role of management is to make sure that everything hangs in balance between technical depth and business needs, and to make sure that the existing processes facilitate that balance.

But if things aren't happening, you don't step in as a ruthless enforcer You look and figure out why, and work with the team together to shift processes to make those things happen.

What are we optimizing for?

He states early on that "[Separate stages of development] must be planned and staffed differently for best utilization of program resources." This describes a world where we have dedicated staff for gathering requirements, different staff for designing the program, yet more staff to write it, another team to test it, and some poor soul has to put our mess into production.

In contrast, most teams today take a much more multidisciplinary approach. Some go to the extreme, and everyone does everything. Most are somewhere in the middle: dedicated testing staff are present, but everyone does some testing; product managers are responsible for requirements, but everyone helps; architects do a lot of design, but each engineer does some architecture.

The key thing though is that last part: "for best utilization of program resources". Here, "program" refers to the project and its staffing, not to the software. And that's the thing, he's optimizing for best utilizing each individual's time and saving money on personnel.

In contrast, modern software development prioritizes other things over direct resource utilization. Time to market, quick validation, all the things to make sure we're going in the right direction. We slow down a little and waste a little bit of each person's time, but we have a lot less backtracking to do.

I could see separate roles making sense in a situation where you do have much clearer requirements. Does something like that exist? Good question. But if it does, separate roles might make sense (I'm not fully convinced, but maybe). For everything else, prioritizing figuring out what we're doing makes more sense than optimizing for full utilization of time.

Write it twice!

One of the best pieces of advice in this paper (not that I'm biased, having written something similar) is to write it twice. The first version should be a fast version to learn what we're doing and gain real-world insight. Then the second version is the final draft that goes to the customer and should meet requirements.

This is great, because it highlights what we run into all the time: we don't know if our solutions work until we try them. We don't really know what the problem is until we try to solve it. Having multiple iterations is a fantastic way to try things, learn those hard lessons, and still have time in the schedule to fix everything.

The recommendation to do it twice, in full, I think is interesting and is something to aspire to. It's easier to advocate for small iterations and small throw-away prototypes, and those are super valuable. If you take nothing else away from this paper, go try doing a throw-away version first.

The gendered language

It's always a little bit of a shock going back and reading a paper from the 70s. Every single pronoun is "he" or "his," and that just really grates1. Not every person on a tech project is a boy, you know.

The norm in tech has pretty well shifted as far as I see. There's still plenty of sexism to go around, but there's less blatant gendered language at least. We've got a long way to go, and sometimes reading papers from the past is nice to remind us of how the norms have changed.

Let's let this remind us that change is possible. Collectively, we've shifted away from default he/him pronouns for anonymous people. We can continue to make a more equitable world. It's going to take a while, it's going to hurt, and it's worth fighting for it ❤️.


As a historical artifact, Royce's paper gives a lot of interesting insights. It's cool to see some of the things he discusses in here be fully realized, and to see other ways in which our field has transcended where it was in the 70s.


1

The USCF's Official Rules of Chess appear to have previously been this way, too. They've made an effort to update them resulting in some inconsistencies, including at least one time where they switched gender of pronouns midsentence while referring to the same antecedent.


If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts and support my work, subscribe to the newsletter. There is also an RSS feed.

Want to become a better programmer? Join the Recurse Center!