Patterns are for People

There’s a meme, originating from certain corners of the Functional side of programming, that “patterns are a language smell”. The implication being that “good” languages either already encode the patterns as language features, or they provide the tools to extend the language such that modeling the pattern explicitly isn’t needed.

This misses the point on rather a lot of levels.

First, it usually originates from the widespread identification of “patterns” as a discipline with a single patterns catalog, the “Gang of Four” book. The argument goes like this: “You don’t need the Visitor pattern in a language where you can apply an arbitrary lambda over any collection“.

Personally, I think this misses some important subtleties of the Visitor pattern, but I’ll let that slide for now. The larger point is that many of the patterns in the GoF are intentionally foundational, and some of them do in fact reflect weaknesses in certain formalist OO languages like C++ and Java. This is the seed of truth to the whole argument.

Unfortunately, it’s a case of throwing the baby, the bathtub, and in fact the entire west wing of the house with the bathwater. I have an entire shelf devoted to patterns literature. (This would be a great point to insert a photo, but my books are currently in transit to Tennessee.) Very few of those patterns are foundational or even widely applicable.

Instead, each pattern reflects deep experience with a particular type of problem. Some of them are about financial systems. Some are about signal processing. Some are about games. Some are about enterprise systems.

Patterns are experience reports. They are institutional memory that transcends organizational boundaries. But more than that, patterns reflect how a particular team, or series of teams, managed to come to grips with a particular type of problem.

When I transitioned from writing software for air traffic control systems to writing enterprise software, I came with a set of implicit presuppositions. Assumptions such as: an object can only be constructed in a valid state. Invalid data must be rejected at construction time.

This turns out to work well for systems that consume only feeds from other automated systems. But less well for systems that interact directly with humans. If I had read Ward Cunningham’s CHECKS pattern for interacting with humans, I would have been much better prepared for the new world I was entering. I would have more quickly comprehended the need for ideas like Exceptional Value, a value that is clearly unacceptable but which is still kept around so that it can be presented back to the user for correction.

Much of my research time lately has been devoted to the study of how programmers and teams of programmers erect shared constructions of reality in order to come to grips with a problem. Patterns are a way of capturing these reality constructions for posterity.

In the end it doesn’t even matter that much if you actually create classes in your code named after patterns, or whether you use equivalent language features, or none of the above. A pattern language is a set of complementary thought-forms that helped some people get their minds around a problem. Ultimately they aren’t about the code you write; they are about how you see the problem in your mind’s eye, and the vocabulary you use to talk to your team about it.

Of course, since patterns guide how you conceptualize a problem space, this means they also have a lot of power to lead you down a bad path. You have to remember that in the end, you need to construct a consensus reality that makes sense for your project. The realities of those who have gone before should be instructive, not prescriptive.

Patterns aren’t tools for programming computers; they are tools for programming people. As such, to say that “patterns are a language smell” makes very little sense. Patterns are a tool for augmenting language: our language, the language we use to talk to each other about a problem and its solutions; the language we use to daydream new machines in our minds before committing them to code. Patterns aren’t a language smell; rather, patterns are by definition, [optional] language features.