
“Design Patterns” Aren't (2002) - Tomte
http://perl.plover.com/yak/design/
======
jfoutz
I remember reading this when it was new.

foreach only works on a list. I can bless a list of lists into a rose tree,
but i can't traverse that in a uniform way. There's just no hook to say, when
the thing isn't a list, get the next element like this. Now days i'd point at
haskell's traversable as the gold standard.

On large java projects it seems like composite/facade for days. Those splits
seemed to let teams work together and not end up with piles of rubble.

A lot of my understanding of programmer fashion back then was pretty fuzzy. It
was easy to ask any team if they were doing extreme programming and they'd all
respond, well, kinda. Ask any team if they were using a pattern language, and
they'd mumble about UML. Sort of the equivalent of well, kinda.

When you have to write a large project like a compiler or a web browser or
something, it's handy to have around. All to often I stare at the empty text
window in my ide and question my life choices. I wonder why i didn't learn to
weld and why i'm a failure at everything i try. The existential dread fills my
soul and i want to just crawl under my desk and cry. In that case, i'll flip
through the GoF. Then i tell that endless abyss "I'm going to use the Command
Pattern!" The abyss slinks back into the corner quietly murmuring until i feed
it a couple beers at the end of the day.

On the other hand, i did quite a bit of perl programming around 2000, so i'm
probably weird.

~~~
skrebbel
From the postscript of this slide deck:

 _It appears to me that almost everyone who has read this has completely
missed the point, even though I said it twice in big letters. People keep
sending me mail that says things like this:

> I just read through you article "Design Patterns" Aren't. I'm afraid you got
> it all backwards. At least the iterator example is totally flawed.

Or people spend a lot of time arguing about how foreach is not analogous to an
iterator pattern, or how it doesn't do the same thing, or how even if it does,
I'm still wrong, because Perl has no analogous replacement for a model-view-
controller pattern, blah blah blah. None of this has anything to do what the
point of my talk. I really wish I'd left out the thing about the iterator
pattern.

Why do people focus on pages 4, 5, and 6 of a 13-page talk, and forget all
about slides 8, 9, 10, 11, 12, and 13, where I make the real point? I have a
few theories. One theory is that most of these people are technical experts.
They're equipped to consider technical issues, but not much else. When all you
have is a hammer, all you can see are the nails. That's what happened to the
guy above who said I "got it all backwards." What? The point of my talk was
that we need to take a fresh look at Chrsitopher Alexander; if I got it
backwards does that mean he thinks we should avoid taking a fresh look at
Christopher Alexander? Or does he think that Alexander should be looking at us
instead? No, he just forgot about everything after slide 7._

~~~
jfoutz
It appears to me that almost everyone who commented on my comment completely
missed the point, even though i made it three different ways.

Why do people focus on paragraph 2, when paragraph 5 is where i make the real
point? Facing a big coding challenge is hard, and having an abstract language
for describing how to structure a solution is valuable to the point of
protecting sanity. I have a few theories. One theory is that most of these
people are technical experts. They're equipped to consider technical issues,
but not much else. When all you have is a hammer, all you can see are the
nails.

~~~
skrebbel
fyi i don't understand why you're getting downvoted, and touché.

~~~
jfoutz
To be fair, it was pretty snarky. It was meant to be silly not hurtful.

In my experience, people pick and choose what they need at the time. I don't
think it's unreasonable to say conversations like this happen all the time.

Dev1: Hey, i need to test my control flow, but i need the register allocator.

Dev2: Oh yeah, I put together a facade for register allocation that just does
LRU and injects the push/pop pairs to do the right thing. I couldn't get away
with a simple interface because there's some weird shared state. The graph
coloring allocator is hard, and will take me some time to get ready.

Facade is kind of code for a leaky abstraction. It communicates a lot about
how the api really works. Most of the stuff in GoF got picked over and teams
took what they needed. Are you doing design patterns? well, kinda. In that
sense, i think it did a lot in the Christopher Alexander spirit.

The original author wasn't wrong, just look at
FactoryFactoryBuilderFactoryMadness from java's crazy times. But i don't think
that's a fair characterization of the entire field of programming.

~~~
mattmanser
The problem is you buried your point in the 5th sentence in the 5th paragraph
of basically a rant.

And it's wrong. No modern programmer does that any more.

When I first came here 9 years ago people would refer to patterns all the
time. But this is the first time I've seen the GoF even mentioned in a year or
so. People stopped caring about design patterns years ago because they stopped
being relevant.

And good riddance, the whole thing was a farce that spawned
factoryFactoryFactories and newbies constantly asking how to implement a
singleton because actually they wanted glorified global variables because they
can't program properly.

Where the GoF completely failed, javascript, ironically, saved us (with
Crockford doing the nudging). It forced functional paradigms, lambda
expressions, anonymous types, function objects, etc. into the mainstream
languages where lisp had failed and almost overnight made design patterns
obsolete. It fundamentally changed _how_ we programmed so that the problems
the patterns aimed to solve weren't problems any more.

~~~
empthought
Design patterns aren't obsoleted by JavaScript; they've just been given trendy
new names like reducers and sagas.

~~~
Jtsummers
Precisely. Each language and domain of programming gets its own set of
patterns. Some patterns are obsoleted (by virtue of being unneeded, or baked
into the language), some new ones are created. Some are amalgams of old ones.

This is the way of the world, design patterns are intended to offer a
language, and languages evolve. The uniqueness of design patterns to certain
domains/languages can be seen as equivalent to the jargon between different
technical fields. It doesn't mean that one set of jargon is obsoleted, it just
means it's inappropriate. The failure, if any, in our world (programming) is
to recognize and emphasize that different levels of programming, different
languages, different operating systems, require different jargon and patterns
and approaches.

------
lfowles
My impression was that design patterns are just shared vocabulary, not
something to aspire to use (other than realizing there was an existing "word"
that would succinctly describe your jumbled spaghetti sentence and using that
instead).

Edit: I've been wanting to read A Pattern Language for a while, but this
snippet from Amazon made me chuckle. If I didn't know better, I would have
given it a 50/50 shot of being from APL or GoF!

>The elements of this language are entities called patterns. Each pattern
describes a problem which occurs over and over again in our environment, and
then describes the core of the solution to that problem, in such a way that
you can use this solution a million times over, without ever doing it the same
way twice.

~~~
rtpg
I think that's what they are in the industry right now. We all use the same
vocabulary, and it makes sense to share a lot, since we're mostly doing the
same thing.

The slides' point seems to be that there's this other concept, which is that
each project should develop a language for speaking of the project, perhaps
more specific to the project. But also not just a list of "things people use
currently". Your new projects could include completely new design patterns.

So the idea when starting a project is :

when designing, define concepts that you will use a lot. For example, you
might be using a lot of iterators. But for the designers of Angular, you're
working with promises, with controllers, with scopes. Use this language when
trying to frame problems, and people will build off the same base.

When people start coding, everyone starts off the same foundation. But that
foundation doesn't need to just be "the design patterns from all over". You
can have your own design patterns, more specific for your project. Have your
best developers choose the right design patterns for the project, and even the
most junior developers will be guided by this when working on the details.

~~~
noobiemcfoob
The last portion of your comment reminds me of the themes from Mythical Man
Month by Fred Brooks.

------
phlakaton
I like his point about Alexander going after delegation of design decisions,
though I don't necessarily think that's the only point he was driving at. From
"The Timeless Way of Building" I got that he's also driving at this:

1\. Modern (not necessarily just modernist) architects are generally terrible
at achieving what Alexander refers to as "living space" because they're
solving for the wrong things.

2\. Small-scale patterns and large-scale patterns can constructively or
destructively interfere with each other from urban planning right down to
construction details of a room.

3\. If you've really mastered design, you can leave behind the pattern
language and cookie-cutter implementations: your solutions will organically
develop with these large-scale/small-scale synergies.

I'd suggest that GoF is a little closer to Alexander in these respects than
the presenter gives credit for, particularly for point #3. The book studiously
makes the point that its implementation of these patterns is not meant to be
the only way to implement them. It also makes no attempt to be an exhaustive
catalog. The fact that some of these patterns have standard and different
implementations in other languages (e.g. iterator method hooks and generators
in Python) doesn't necessarily mean that the pattern itself is useless outside
of its OOP niche.

I'm glad WikiWikiWeb is back up so we can debate all of this on the one true
forum for debating design patterns. :-)

~~~
lugus35
Design is a kind of Constraints Satisfaction Problem (CSP).

[https://en.m.wikipedia.org/wiki/Constraint_satisfaction_prob...](https://en.m.wikipedia.org/wiki/Constraint_satisfaction_problem)

------
shubb
I've always seen design patterns principally as a way of communicating what
you are doing to other programmers who come later.

For instance, MVC is a very popular design pattern. When you read code built
according this pattern, even if you are not familiar with the language or
framework, you know what kind of thing to expect to find in different parts of
the program.

They can also be useful in a context where not everyone in the team is used to
writing code in a disciplined way - like coding standards and ideas like
YAGNI, they can give an objective set of standards at code review. Adopting a
few of these strategies in a code base provides a standard people can refer to
about what goes where. Where the question is whether James should have stuck
this database code in the class that renders the web page, being able to point
to a well documented strategy and say "that code doesn't go there because
we're doing that" can be better than excessive conflict.

The author is right that if you have a common problem, you should probably be
solving it with a library (preferably someone else's). However, often these
libraries and frameworks are implementing the generic bits of the design
pattern, and understanding that pattern gives you a shortcut to knowing how to
use them well.

~~~
throwsincenotpc
> For instance, MVC is a very popular design pattern. When you read code built
> according this pattern, even if you are not familiar with the language or
> framework, you know what kind of thing to expect to find in different parts
> of the program.

The problem with MVC is that it lost any accurate meaning.If you tell me "my
app is MVC", I vaguely understand it has a view, a controller and a model but
it doesn't tell me if the controller sits between the view and the model or
the view directly observes changes in the model.

If you take a pattern like the Chain of Responsibility, or the Command
pattern, the goals are clear because they are usually made of a single or at
most 2 collaborators. MVC is sometimes a mix between the strategy and the
observer, sometimes it isn't yet people still call that MVC.

~~~
shubb
The major problem for me with MVC, is that people build complex applications
on an MVC framework and then try to shoehorn various things that are
definitely not views, models, or controllers, into the pattern.

I've seen applications that control hardware where a class called 'model'
twiddles bits on an interface port and then blocks until it sees some bits
twiddled in response. Or where the 'controller' actually goes off for an hour
to do heavy data processing (using the web servers thread pool as a job
queuing system).

In both these cases, those things should have been in descriptively named
classes that accurately described what they did. In the latter case, trying to
adhere to a pattern gave the application a strange architecture that could
have unforeseen problems.

I'm not sure if MVC is even the right pattern for a lot of modern web
applications with a thick client or that describe a workflow. Often it feels
like you are shoehorning there.

However, I'd say these are cases of 'doing it wrong' that don't prove the
overall approach bad. I picked MVC because everyone has heard of it.

~~~
mcbits
This is why I disagree with the shared language interpretation of design
patterns. Once you slap "MVC" or any other name on some code, you'll
constantly be second-guessing whether new code is violating the pattern. The
goal is to produce working, efficient, secure, maintainable software, not to
implement patterns.

I think design pattern books would be more helpful if they deleted all the
pattern names and just called the book "A collection of a-ha! moments in C++"
or whatever. Readers could skim through the chapters every couple of months
until they stop having a-ha! moments. The "patterns" may or may not emerge in
the reader's code, depending on what works best for a specific project.

------
kornish
The core points of this talk, as noted in the Addendum [0], is that "we need
to take a fresh look at Christopher Alexander".

Since that point has been established, it would make a phenomenal follow-up
talk to take Alexander's book, which is from the 1970s, and begin a discourse
on how his ideas can be applied to modern software engineering and
architecture. While the reader takes away from the slides that Alexander has
some unique ideas that are probably useful, he/she doesn't come away with a
good understanding of what they might be. (though if anyone knows of talks
that discuss Pattern Languages, I'd love to see them!)

[0]:
[http://perl.plover.com/yak/design/samples/note.html](http://perl.plover.com/yak/design/samples/note.html)

~~~
asolove
Or, indeed, to look at Alexander's work since this book, which has gone in a
direction very similar to the programming world. In "The Nature of Order",
Alexander shows how the idea of "good design" is actually best analyzed as
just the output of "good process": design is about how a thing unfolds over
time and becomes more itself through gradual refinements and responding to its
environment.

The bigger complaint about software patterns is that, unlike Alexander's
original patterns, they are merely tools useful to build any kind of program.
Alexander's patterns were meant to only be useful in building humane places
with humane processes. You literally could not build a mass prison with the
construction methods he describes, because they aren't amenable to mass
production, design from afar, or economies of scale.

Exactly the opposite is true of our usual application of "software patterns".
They are often used to produce software that is inherently immoral.
Alexander's patterns describe an environment of decentralization of decision-
making about both architecture and the community it inhabits. Meanwhile, our
"software patterns" embed a centralized power structure both in the code
(architect->team lead->junior programmer) and in the world now increasingly
controlled by the whims of Silicon Valley founders.

I wonder what it would look like to describe low-level primitives of
computation, similar to Alexander's new low-level architectural methods, which
actually made decentralization of power a reality and resisted economies of
scale. They certainly wouldn't look like the Gang of Four patterns.

~~~
acomar
> Meanwhile, our "software patterns" embed a centralized power structure both
> in the code (architect->team lead->junior programmer) and in the world now
> increasingly controlled by the whims of Silicon Valley founders.

None of these things is obvious to me. In fact, this whole paragraph veers in
the direction of a conspiracy theory. The rest of your post is quite
interesting and I agree that the design of our software should tend towards
the human and humane.

> Exactly the opposite is true of our usual application of "software
> patterns". They are often used to produce software that is inherently
> immoral. Alexander's patterns describe an environment of decentralization of
> decision-making about both architecture and the community it inhabits.

You should expand on this.

~~~
asolove
I certainly don't mean to imply a conspiracy theory, any more than Alexander
would say that the past century of poor architecture is deliberately brought
about by a conspiracy of architects. It's simply a case of the environment
bringing about bad results naturally.

His critique of architecture is this: the quality of a building comes from a
process which has to unfold over time and take into account very minute
preferences of the kinds of people who will actually inhabit it. A good house
design can't be measured by the plans, but only by living in it and seeing
what kind of life occurs to the people who are there. Therefore, if you build
it by one person's design, or because the renderings look nice as a 2d
composition or as a 3d model, or to reduce costs by repeating the exact same
things over and over, you will necessarily end up with a bad building. It
won't be bad on purpose, but the power structure of the process that built it
will have made it bad. (Maybe an architect wanted to win an award, or a
developer wanted to sell the properties quickly without worrying about the
owners' long-term experience, etc.) And if you want a better building, instead
of arguing about design, you should just find a process where more of the
decision-making is made by the kind of people who will inhabit the house.

The same is true of software. I do not think most people set out to make bad
software. But Conway's law tells us that the result will reflect the
organization and process by which it was created. If the process of creating
the software is embedded in a large corporate structure where VPs are
fighting, that politics is necessarily felt by developers and even embedded
into the system. If the process of creating the software is embedded into a VC
unicorn and its only chance of growth is to destroy local communities or
mistreat workers on a large scale, that will happen.

This is even true just for the people building the software. I've worked at
companies where the design team had the power, where the engineering team had
the power, or where the project management tool had the power. The same people
might work with the same goals, but in these three environments they will
produce three very difference pieces of software. And I've worked at companies
that had the power to trick money out of customers, which soon replaced the
desire to actually provide customers any benefit, and produced its own unique
form of engineering environment.

Alexander's critique is aimed at the very idea of "scalability": any one
person or process who can determine the way architecture (or software) behaves
for thousands of people will get it wrong. Not because the person is bad or
the decision is inherently wrong. But because no one decision could possibly
be right for all of those people.

------
mvindahl
I loved the GoF book back in the days. I recall it as very well written and
very much directed at solving practical problems. Those properties alone set
it apart from most books that I encountered during my time at the university.

Being new to Java at that time, the GoF patterns were also a very useful
crutch to me when trying to learn to "walk" in the bright and futuristic world
of class based OO. And it provided me with a common vocabulary that would ease
communication with coworkers.

These days I find the GoF patterns to be a bit dated. A lot of it had to do
with patching the shortcomings with the popular languages of the day; mostly
C++ but Java had the same kinds of issues. A good deal of them could be
paraphrased as "alas, functions are not 1st class citizens but as a workaround
let's wrap them in an object" or "alas, our language does not readily support
the common need to do X, so here is how to implement X ourselves". Someone
once noted that design patterns are really language smells and I think that
hit the nail on the head. The GoF patterns are really a catalog of the pain
points of C++ (and similar strongly typed, class based OO languages).

In recent years I've had the pleasure of working in Javascript. Does GoF apply
to Javascript? Not really. Does Javascript have design patterns? I'd say yes
but there are fewer of them. Promises are really a design pattern to ease the
pain of working with callbacks. Using function scope to hide private variables
is a design pattern to deal with the lack of having private sections of the
code. The module systems such as CommonJS deal with the lack of language level
packages, and also provides a solution to isolating code in a well defined
way.

Bottom line is that design patterns are not universal in any way; they are
very specific to the type of language that they deal with. Also: Language
designers better pay attention to the design patterns which evolve over time
since each one points to a potential improvement of the language itself.

------
fusiongyro
MJD says Alexander's central question is "How can you distribute
responsibility for design through all levels of a large hierarchy, while still
maintaining consistency and harmony of overall design?"

The only "solution" to this question in software that I'm aware of is, "hire a
charismatic architect and let them do all the design" which is terrible.

Thinking about my team, I'd say probably a third of them are interested in
architecture at all, and of that third, at least one has a punishingly
minimalist aesthetic that the rest of us loathe. The rest of us are fairly
scared of being wrong, scared enough to avoid making bold decisions.

GoF may be insufficient, but it's really the only pattern language we have. I
don't even know how to think about this idea properly, which I consider a
symptom of the author being onto something.

~~~
fatdog
Good architecture is leadership based on transparent principles.

The hardest thing for a lot of people to hear is, "you're not wrong, but the
thing you're thinking about isn't the essential one." Architecture is about
finding the principles and axioms that apply to the situation. It also
requires an ability to "let go," in that if your design is good enough, you
are no longer personally necessary because the rest has been made obvious, and
anyone can implement it.

Elegant thinking can seem obvious, and transmits a great deal of understanding
simply. The purpose of architecture is to formulate something that benefits in
scale to the efforts of multiple cheaper, less experienced people.

~~~
fusiongyro
I think what makes that even harder is that I've never even thought of saying
that, and it's exactly right.

Thanks for elaborating on this.

------
DonaldFisk
Christopher Alexander's books:

    
    
        https://archive.org/details/TheTimelessWayOfBuilding
        https://archive.org/details/APatternLanguage
    

It's also worth reading Patterns of Software by Richard Gabriel:

    
    
        http://www.dreamsongs.com/Files/PatternsOfSoftware.pdf
    

who draws heavily on Alexander's work.

~~~
mark-r
Patterns of Software is worth it just for the Forward.

~~~
EpicSolo
I couldn't find "Forward" in that book, what exactly is it?

------
mmahemoff
"The Gang-of-Four idea is to discover existing patterns of software
development. Then program people to implement them habitually"

Citation needed.

GoF's intention was to give people a tool for thinking about architecture and
sharing their experiences with others. If people are "programmed to implement
them habitually", that's some manager's fantasy and neither in the letter or
spirit of Design Patterns.

It's be like seeing a programmer blindly use jQuery without understanding
JavaScript, and blaming it on jQuery instead of the programmer. A tool that
can be used badly, even one that lends itself to being used badly by a certain
population, doesn't automatically mean the tool itself is rotten.

~~~
throwsincenotpc
> that's some manager's fantasy

The issue is that in a lot of shops design patterns have turned into a
religion and not just a tool to help thinking. I've seen managers like that.

If you didn't implement 15 different design patterns in this or that code base
that was "bad design", even if it unnecessarily made the code more complex.

I've seen iterators classes written when a simple for loop would have done the
trick. I've seen chains of responsibility implemented when a basic switch
statement would have been enough. Of course the code wasn't meant to be
refactored in anyways. In fact complexity led to inability to refactor
anything as nobody had a clue what went where ... and of course to manage all
that bullshit we had to write tons of factories, because instantiating a
single useful object now took 30 lines of code ...

~~~
mmahemoff
Agree, that's a real issue, just like managers who treat agile as a religion
and sadly give a fundamentally good thing a bad name.

Good programmers know the importance of YAGNI and the root of all evil that is
premature optimisation. They should be well equipped to avoid over-engineering
while still getting the learning benefits of patterns.

Chain of responsibility, for example, is a pattern I learned via GoF, have
found it to be useful on several occasions. I quite possibly never would have
known about it otherwise. At best, it would be left to chance for me to
stumble on it or refactor into it enough times to recognise the pattern.

------
mjd
My further thoughts on this, from 2006, are in this blog article, “Design
Patterns of 1972” [http://blog.plover.com/prog/design-
patterns.html](http://blog.plover.com/prog/design-patterns.html)

------
thom
Two years after this was published, Domain Driven Design was released, which
among other things talked about using a ubiquitous language to ensure all
members of a team creating some software were on the same page. So it seems
disingenuous to imply the software design community were completely oblivious
of these nuances in Alexander's work.

More widely, addressing the slightly snidey remarks about C++, which form the
basis of most attacks on design patterns - this idea that design patterns are
snippets of code certainly did take root, and persists to this day. Even with
DDD, people missed many of the more interesting 'soft' factors addressed, and
walked away from the book thinking all they needed to do was rename their data
access objects 'repository'.

But it's utterly useless to say that iterators as a concept are pointless
because foreach exists (and whether or not the author wants to believe people
are missing the point, this is the foot they launch off from). Languages with
first class functions are popular today, and I still hear that you don't need
the strategy pattern because of this. And yet I look at Python's urllib
(literally today), and its retry mechanism is configured by supplying a value
telling it what to do. It's doesn't expose an interface to make the decision
yourself. Design patterns in software (whatever the ancestry of the phrase)
give you a better granularity to discuss, think about and plan software
design. Sure, we have more retrospective patterns, but that's as much to do
with the fact that we make a ton more software than architects make buildings.

I certainly agree that we haven't, as a community, got full value out of even
our own interpretation of design patterns. But I don't think it's because of
any of the issues described in this talk, and I certainly don't think it's
because of the limitations of our programming languages.

------
nickbauman
Design patterns are mostly cultural. They're about getting people to speak the
same language about designing a system. In languages like C++ and Java, the
culture is needed to overcome the paltry capability of those languages to
re/compose well. Other language communities don't need this.

If you read Alexander's interviews in Stuart Brand's _How Buildings Learn_
you'll see he's mostly concerned with how to connect people directly with the
problems his buildings and urban planning are trying to solve. It's highly
cultural. He rails against what he calls "magazine architecture" where
buildings are designed mostly to photograph well, their inhabitants's problems
with the buildings are an afterthought. Sounds familiar?

------
ryanisnan
I'm somewhat familiar with the GoF book and Alexander's A Pattern Language
book and I must say, I don't really understand this post.

I wish I had the latter in my hands now for reference (it's at home), but from
what I can recall, the book goes into great detail about how to solve specific
problems using generalizable solutions. For example, to establish a connection
between the space inside of a building with the space outside of the building,
consider adding awnings with open archways to the perimeter.

The Design Patterns book, though wildly specific (possibly only because it can
be), also deals with solving specific problems with generalizable solutions.
For example, creating and ensuring only one instance of an object exists
(Singleton - p. 127). The book outlines the motivation for this (e.g. the
problem), and defines an abstract for the solution.

Also, the fact that more modern languages can more easily solve some the
problems discussed in Design Patterns is, while true, seems like a bit of a
red herring. Undoubtedly the patterns themselves have a lifetime of
usefulness, and will evolve as we discover new ways of solving new (and old)
problems.

------
throwsincenotpc
Design patterns are just a way to convey an idea. If I name something a
factory, everybody knows its purpose. If I name something a prototype then
people who are familiar with patterns know it will have some "clone" method.
So it's a bit like UML redux. But one only need iterators if the language one
uses doesn't allow you to naturally express custom iteration without requiring
you to write a class or some other boilerplate.

The article demonstrates that fact pretty well.

It's also a good way to judge how practical a language is. I don't need to
write iterators in a language that has generators for instance. I don't need
to write factories in a language that supports closures... But then people
selling all these expensive modelling tools would be out of business ...

------
tptacek
Also from Norvig, same basic idea, minus the Alexander appreciation:

[http://norvig.com/design-patterns/](http://norvig.com/design-patterns/)

------
rando_2458976
I agree with the author's main point (software engineers should take another
look at how Alexander frames the patterns in "A Pattern Language"). Obviously
we should all look for common patterns and problems in our work and build up a
shared "vocabulary" of approaches to those situations.

But these pattern catalogs present a risk of seeming complete. To believe that
you're near completion on a list of patterns in any field is utter hubris.
Alexander's own hubris at having discovered objectively "correct"
architectural styles led him down a path towards obsolescence while the rest
of the architectural discipline moved on. The hand wavy "scientific" surveys
Alexander conducted wouldn't pass a basic social science methods review these
days. Pseudoscientific methods of assembling anecdotes or interviews from
small samples that don't control for sampling bias will always result in some
interesting insights that can't be reliably generalized beyond the narrow
scope from which they were gathered. That's what both of these pattern
languages are. At best they are a handful of neat ideas that other
practitioners can reuse. But these are not some sort of reliable canon. We're
all going to have to do more rigorous research if that's what we want.

There might be another parallel in here about the fetishization of
anachronisms. Alexander, who is an architect not a carpenter, goes out of his
way to glorify hand-crafting things (literally avoiding power tools). Unless
you're a carpenter who specializes in make "artisanal" works of art for
wealthy patrons, I guarantee you'll enjoy the productivity gains of a
pneumatic nail gun. So if you ever find yourself insisting that some old
"pattern" is more pure at the expense of everyone else's productivity, double
check whether your dogma is worth it.

TL;DR. Don't take patterns too seriously. Always look for new ones.

------
programminggeek
The bigger problem often is...

We don't often understand what we are building most of the time.

Software is a communication tool most of the time. You are communicating
between machine and user or user to machine to network of data and so on.

Most of the code is really a translation from input to some kind of command or
process and outputting the result.

The more layers you add to that, the further you are from the truth and the
more confusing the world truly is. For all the patterns, abstractions, and so
on that we lean on, we miss out on the most important one...

input -> processing -> output

~~~
TeMPOraL
> _We don 't often understand what we are building most of the time._

Indeed. Programming is a process of constant discovery and reframing of the
problems ahead.

> _Most of the code is really a translation from input to some kind of command
> or process and outputting the result._

I disagree. This may be true in a general form, but a general form like this
is of little utility. There are many types of programs for which the focus is
state manipulation, and what you care about is that state - whether in its
final form (e.g. 3D modelling software) or in its evolution (video games). The
classical output here is just a snapshot of state. I don't think trying to
squeeze everything into a "dataflow" paradigm of input -> processing -> output
is a good idea.

Also, in context of design patterns - the problem is that even if we take
"input -> processing -> output" assumption, the space of possible outputs is
_huge_ , and the criterion for acceptable outputs is _very complex_. It is
this complexity that makes our code complicated, and the reason we have to
build layers of abstraction is because our minds are pretty limited and we
can't handle much complexity directly.

------
hota_mazi
Design patterns are good practices that emerge when a language is used by a
lot of people. That's it. Nothing less, nothing more.

There are two kinds of languages: languages that have design patterns and
languages that don't have a lot of users.

~~~
goatlover
So Haskell and Lisp are just lacking users? It has nothing to do with language
design?

~~~
shados
Those languages have a ton of patterns. Heck, not only they have patterns, but
some of the patterns are studied to the point of having an entire branch of
mathematics dedicated to them and have countless properties that can be proven
about them. They even predate the language (Category Theory)

------
mindcrime
This guy clearly doesn't understand the iterator pattern!

J/K'ing. But he consciously chose to give the talk a "click bait" title, and
the goat thing was a bit of hyperbole. Totally reasonable things to do, but
know that you have to live with the backlash from that.

All of that said, I agree with this core point that "we need to take a fresh
look at Christopher Alexander". I plan to go out and get a copy of the pattern
language book and read it sometime soon, to get a better perspective on "real"
Alexanderian patterns. This was a handy reminder to do that.

~~~
elihu
It's worth mentioning that "A Pattern Language" is just that, it's a language
of about 250 patterns that can be applied to urban design, building layout,
and construction. If you want to know more about design patterns and how and
why Alexander came up with the patterns described in "A Pattern Language" in
the first place (which is helpful if you want to create a pattern language of
your own to address the needs of a different field), you might be interested
in "A Timeless Way of Building".

(I would recommend reading or skimming through "A Pattern Language" first, to
get a good idea of what Alexander's idea of a well-formed pattern is. It's
also a really interesting book in its own right, especially if you have any
interest in architecture.)

------
pmontra
The key slide is
[http://perl.plover.com/yak/design/samples/slide011.html](http://perl.plover.com/yak/design/samples/slide011.html)

My understanding is that Alexander's patterns applied to software would be the
typical components of a software system (DB, queue, API, etc). The GoF
patterns are about how to build those components. They are lower level.

We need both, but don't we already have both?

------
randcraw
I have to agree with the OP that Alexander and the Gang of Four (GoF)
approached design from very different angles. It looks to me that the two
groups never shared a common vision at all.

Alexander is talking about 'spaces' in buildings, how they take shape, how
they interact, and how they serve the greater style and purpose intended by
the master architect to serve the lifestyle of the resident. Here design
focuses on the end product and how it will function for the _user_. These
design patterns have nothing to do with how the building was constructed or
the experience of the tradesmen who built it.

In contrast, the GoF book did not talk at all about the final software end
product, but only the process of _building_ it. The emphasis is entirely on
the tools of the tradesmen and encouraging their proper use and re-use. Such
design patterns do not reflect the user requirements or even the architect's
high level design of the software product, much less serving the user
experience in a consistent purposeful way.

However it seems to me that Alexander's approach to patterns _could_ have been
adopted in the software domain, but I think that would have looked a lot more
like Jef Raskin's style guide at Apple which encouraged developers to adopt a
common holistic yet systematic approach to Mac software so that the user
experience was served. I think Raskin wanted apps to fit together the way that
rooms in a well designed house flow from one to the next -- something
Alexander would endorse, I think.

Another variant on design patterns in the software that might have worked
well, at a level that might have bridged Raskin to the GoF, could have been
Alan Kay's model for objects. The higher level conventions for components and
behaviors that Kay espoused might have made for an interesting basis for
patterns like those of the GoF. But without Kay, much less Raskin, the very
modest ambitions of today's notion of software design patterns led nowhere but
software reuse -- an inauspicious end to Alexander's vision, IMHO.

------
YZF
It's been a while since I read the GoF but my recollection is that it was
fairly language agnostic and also quite focussed on problems that arise when
building the UI monoliths of the time. While it was an attempt to capture
something fundamental it ended up, in many cases, capturing something that is
more reflective of the period, including things that have to do with languages
of the period, the types of applications, and the prevalence of OO. In
contrast, Pattern Language, which I've also read a long time ago, naturally
benefits from a broader perspective because while humans have been building
software at scale for something like 30 years, we've been building buildings
at scale for thousands of years.

I feel like GoF was pretty useful in a moment in time where a lot of people
were facing similar problems and could benefit from canned solutions to those
problems. For the most part are not the problems that I'm trying to solve
today aren't really related to those monolith UI application and the tools
that I use have some patterns already built into them that I tend to follow.
So seems it's something that's useful to study, in the right context, learn
something from, but not necessarily copy/paste patterns from.

------
elihu
> The problem Alexander is trying to solve is: > How can you distribute
> responsibility for design through all levels of a large hierarchy, while
> still maintaining consistency and harmony of overall design?

> The pattern language does not tell you how to design anything

> It helps you decide what should be designed

> You get to make up whatever patterns you think will lead to good designs

I'm not sure I completely agree with this. I agree Alexander was trying to
establish a vocabulary for communicating common ideas, and I agree that his
collection of patterns wasn't meant to be the one true canonical list of
architecture patterns, but I do think a lot of his patterns do specifically
tell you how to design things. Also much of what he wrote isn't specific to
large construction projects with many stakeholders ("The Oregon Experiment",
which I haven't read, is an account of the process of designing the University
of Oregon campus. However, "A Pattern Language" would also be of use to a
person designing their own house by themself.)

What makes A Pattern Language more interesting and intellectually honest than
just a list of design rules is that he gives justifications for each pattern
and tells you what problem they solve and why he believes them to be an
optimal solution. Anyone else can come along and propose a better pattern that
solves that problem (or a more general one) in a better way, or can provide
some argument that the problem isn't really a problem in certain
circumstances. There's no appeal to authority or tradition; patterns are
judged solely on their merits (to the extent that we can understand what those
are; architecture is strongly tied to psychology, which isn't entirely
understood).

(I really wish that someone would write a book similar to A Pattern Language,
but about music theory.)

------
danblick
In the last year I've learned a little bit about _expert performance_ from the
book "Peak" and also the Coursera course "Learning how to learn".

Experts learn to think and act more efficiently by forming "chunks" \-
associations between different concepts that are recalled together and can be
handled as a larger unit (which reduces the amount a person needs to keep in
working memory).

I think this really has a lot in common with "design patterns", which are
basically "chunks" of design expertise that have been written down and can be
recalled by name and shared between people.

(Also, if you haven't looked through "The timeless way of building", do it!
It's a beautiful book about architecture and the role of individuals as a part
of society and how our environment shapes our lives. When I open it I feel
transported to 1970s Berkeley.)

------
infinity0
This is what strongly-typed functional programming languages have been
teaching and preaching and practising for years.

~~~
oomkiller
Can you provide more detail, this is very intriguing. Do you mean that the
types are the patterns?

~~~
throwsincenotpc
Not the OP but let's take a tree. In F# it's trivial to describe what a tree
structure is with the type system. In Java, you'll need to use the Composite
pattern and write classes (tree + leaf) to create a tree like structure. Thus
the Composite pattern is made irrelevant in F# since an algebraic type system
allows you to describe an intent without writing imperative code.

[https://en.wikipedia.org/wiki/Composite_pattern](https://en.wikipedia.org/wiki/Composite_pattern)

[https://en.wikipedia.org/wiki/Algebraic_data_type](https://en.wikipedia.org/wiki/Algebraic_data_type)

Good type systems are a trade-off between complexity and expressiveness, but
it's something that is hard to get right. Obviously Java's type system is
simpler thus in theory easier to learn. But in practice F#'s is easier to use
if understood and might lead to smaller thus more maintainable code bases.

------
overgard
So, to summarize:

1) Iterators are pointless because perl has foreach. (Which entirely misses
the point of why you'd want to abstract the concept of iteration from the
container. (Hint: try using foreach on a tree.))

2) A bunch of trash talking about other languages type systems. (Incidentally,
even when this was written, those criticisms were untrue.)

However..

3) According to the postscript, we should ignore the bogus parts I just
mentioned above and just focus on the parts that are right. I'm guessing this
is the "throw spaghetti against the wall and see what parts stick" school of
persuasion, where you can just say a bunch of shit that's obviously wrong and
then tell people to ignore those bits.

So basically, the point of this talk is "go read Christopher Alexander's book"

------
lisper
The thing very few people seem to get about Design Patterns (in the gang-of-
four sense): they are not a Good Thing, desirable and worthy of study in and
of themselves. They are a necessary evil to compensate for fundamental
deficiencies in C-like programming languages.

~~~
smnplk
Especially object oriented languages.

~~~
yesiamyourdad
Especially functional languages.

I remember this whole talk now. I actually have an acknowledgement credit...
holy crap. That was a long time ago.

Here's how I see GoF: it was a brand new idea to programmers. GoF was trying
to open some eyes to the idea that there were already all these patterns in a
lot of software. They called out a few of them. Some are really classic. Some
were total misses (how many of you have implemented State?)

GoF was also coming from the Smalltalk world and trying to preach what they'd
learned so C programmers could understand it.

So in 2002 when MJ Dominus wrote this, a lot of us were feeling a lot of
stress about the rise of Java and C#. A lot of the appeal of these languages
was the promise of never having a memory leak. A side benefit was that Java
especially didn't enable some of the really risky C++ practices (MI,
overloading short circuit operators... basically most of Scott Meyers'
"Effective C++" books). But if you were any good at C++, you gave up a lot.
Generics were the big pain but I remember at the time really missing the STL
<algorithm> library.

MJ was (is?) a Perl / dynamic languages guy. There was vigorous discussion in
the "blogosphere" (gag) over the static/dynamic language debate. MJ was
basically saying to think bigger than these trivial little patterns. GoF is to
software architecture is like nails & drywall are to an architect.

------
pjmorris
> Alexander's central question is "How can you distribute responsibility for
> design through all levels of a large hierarchy, while still maintaining
> consistency and harmony of overall design?"

To the degree I understand Alexander's central answer, it is "Put the needs
and wants of humans who are the users of the design at the center of all
design, planning, and building (and heve them do the design, planning and
building, where possible.)" If that's close to true, then making things that
are programmable is more important than 'getting it right the first time'. One
can always take a chainsaw or an editor to a bad decision.

------
partycoder
Well, design patterns are an abstraction.

You can build an abstraction where a car as a particle for a thought
experiment or where a car is 3d vehicle with a deformable chassis for crash
simulation. Both can represent a vehicle to certain level of detail. The
correctness of using each level of detail is very context sensitive.

To model a problem after a design pattern can have a lot of overhead, but it
can objectively produce a working solution.

Now, if the design pattern is really a way to solve a problem in terms of
constraints imposed by a type system or a language, once you add, change or
remove those constraints the problem solving approach might stop making sense
or being optimal.

------
omginternets
In a similar vein, I found Alex Martinelli's talk on design patterns very
level-headed and instructive:
[https://youtu.be/0vJJlVBVTFg](https://youtu.be/0vJJlVBVTFg)

------
rezashirazian
I personally like to implement design patterns when I'm learning a new
language. Last year when I decided to learn Swift I did just that. I took on
ten different made up problem and solved it using one or more popular design
patterns. I wrote up a blog posts and uploaded a final repo for each solution.

If you like to check it out, you can find it here:
[https://shirazian.wordpress.com/2016/04/11/design-
patterns-i...](https://shirazian.wordpress.com/2016/04/11/design-patterns-in-
swift/)

------
wwweston
> The "Design Patterns" solution is to turn the programmer into a fancy macro
> processor

To be fair, it is far from the only source of motivation to see programmers as
(or turn them into) a fancy macro processor. Maybe that's one reason why shops
where discussion orients heavily on design patterns often also seem to be
places where Management Theory X [0] is on display.

[0]:
[https://en.wikipedia.org/wiki/Theory_X_and_Theory_Y](https://en.wikipedia.org/wiki/Theory_X_and_Theory_Y)

------
AstralStorm
Fortunately C++ is finally out of the coma and now the Concepts part is being
looked into. This should finally make it possible to make many patterns truly
generic without excessive amounts of template voodoo. (or Boost, which is a
library of voodoo) One iterator for everything that is a RandomAccessSequence,
etc.

Concepts are supposed to be the Design Patterns in the sense mentioned in the
slides. But they could use more user friendly names. (no, I do not mean
developer friendly)

------
fit2rule
I wholeheartedly concur with this ethos, and agree with the principle
statement that it is the _Language_ which matters, more than the patterns
themselves.

Computer software is a form of literature. The most important thing is how
well the language of this corpus persists. That only happens through usage.

Thus, by slide 6, I was prepared for a "because: Lisp" argument, and .. there
it was.

------
kageneko
I was at that talk. YAPC in St. Louis. (WUSTL?) At the time, I didn't know
much about the Gang of Four and I had never heard of Christopher Alexander.
Even many many years later, this talk has stuck with my and I spent time
looking up Christopher Alexander and reading about some of his ideas. Also, I
told everyone I knew about him :D

------
george_ciobanu
I think he just means "Design principles" in the as foundational ideas that
keep many decisions clustered together. E.g. "Always have a default option; if
more settings are needed, make them available but hide them away from the
'main path'".

------
LordDragonfang
I'm a bit young for perl, but I've had rather extensive experience with python
at my last job, and it's my understanding that perl has a similar "global"
solution with

    
    
        for elem in collection:
    

and the `__iter__()` function. Correct?

~~~
rurban
no. perl5 can deal natively only with finite lists, not general iterators over
infinite (lazy) lists. of course you can design an iterator over lazy lists,
but you got no language support as with __iter__, other than using tie
callbacks.

only perl6 supports lazy lists and coroutines and yield.

but iteration is only a trivial part of a design pattern. as the name says, a
pattern is matching certain conditions, like number of arguments, types of
arguments, context, ... and applies a specific solution to this pattern. perl5
and perl6 are not functional enough to provide this kind of pattern matching
and functional dispatch. python and ruby neither. perl6 has multi-methods, but
no proper matcher.

Norvig explains a bit in [http://norvig.com/design-patterns/design-
patterns.pdf](http://norvig.com/design-patterns/design-patterns.pdf), but in
essence any strongly typed FP deals with that.

~~~
falsedan

      > but you got no language support as with __iter__, other than using tie callbacks.
    

What are tie callbacks, if not (creaky) language support?

Also the perl way would be to implement infinite streams, ala MJD's HOP[0].

[0]:
[http://hop.perl.plover.com/book/pdf/06InfiniteStreams.pdf](http://hop.perl.plover.com/book/pdf/06InfiniteStreams.pdf)

------
fourthark
I didn't think you were supposed to copy the code out of the book. GOF was
trying to define the vocabulary, and the code was just examples.

------
kevinpet
From the description, it sound like Domain Driven Design is a better fit for
"a pattern language" than software patterns are.

------
expressalive
Very interesting, a lot a truth, many design patterns have become useless in
some languages as the language itself solves the problems.

------
0xAA55
Ancient cruft from an arcane language and other neat thoughts about scripting
languages from 2002.

------
denalilumma
"The pattern language does not tell you how to design anything. It helps you
decide what should be designed. You get to make up whatever patterns you think
will lead to good designs."

Impressive insight.

------
miloshadzic
I remember reading this some time after reading "Notes on the Synthesis of
Form". He's absolutely right.

------
Fifer82
"But the C++ macro system blows goat dick" teehee

------
danharaj
Via the curry-howard-lambek(-...) correspondence, Category Theory is a pattern
language for programming. It has a very rigorous criterion that justifies
calling a logical/mathematical/programmatic construct a pattern: a pattern is
a universal construction. Bear with me if you would like. I'm doing this off
the cuff and I doubt I'm good enough to communicate what I want in a single
Internet comment :)

A universal construction, at the vaguest level is the most general way of
solving a particular problem. For example: What is the universal way to
construct a program that produces two values?

Via curry-howard: A program is an arrow from f : A -> B. We call A and B
types, they are like specifications of the environment a program takes and the
environment it produces. e.g. (+1) : Int -> Int is the program that takes an
Int and produces another Int, by incrementing. We also have a way of composing
programs, (.), which to young mathematicians is function composition, to older
mathematicians morphism composition, and to nixy programmers the pipe operator
(in reverse). (+1) . (x2) : Int -> Int is the program that first multiplies by
2, and then adds 1.

We want a solution that produces two values from the same environment. Such a
solution looks like f : W -> A, g : W -> B. That is, we have two programs that
take the same environment and each produce their own value.

Let's say our language has product types. That is, given a context A, and a
context B, we also have the context A x B. This is a very natural thing to
have. A language with pairs/tuples has such a type. What makes product types
special is that they come with functions proj_1 : A x B -> A and proj_2 : A x
B -> B which do the "obvious thing". That is, the first one just gives you the
first element of the pair while the second just gives you the second element
of the pair. I claim that this type and its projections are the universal
solution to the problem of constructing a program that produces two values.

What do I mean by that? I haven't defined at all what universal means. See, I
don't want to give the rigorous definition because it is very abstract and I
think it takes a lot of pondering to really understand it. Instead, let me
wave my hands some more and give references at the end: A universal
construction is something that solves a problem in such a way that any other
solution to the problem can be transformed into an instance of this
construction.

The functions proj_1 and proj_2 are not the only feature of product types.
They have another feature, and it is that, given a solution f : W -> A, g : W
-> B, there is a _unique_ way to produce a function W -> A x B, that is, there
is a program that converts our solution into a product type. This is usually
denoted < f, g > : W -> A x B. Furthermore we have that proj_1 . < f , g > = f
and proj_2 . < f , g > = g.

This might either be complete nonsense, a triviality, or something you already
understand. This definition of product, when made rigorous and with all its
details written in, transfers from programming languages, to logics, to set
theory, to algebra, to topology, to geometry and beyond. It is a pattern, and
you can use this pattern wherever you find it. And where you _don 't_ find it,
usually there's significant reasons why it can't exist.

[https://en.wikipedia.org/wiki/Universal_property](https://en.wikipedia.org/wiki/Universal_property)

~~~
AstralStorm
And nobody cares because it is easier to just use a word Set. Or Program. (in
Church-Turing sense, and not awkward Curry-Howard isomorphism)

A true Program is not really an Arrow, as it deals with mutable unknown state
that cannot be reduced to a known set of inputs completely. (Where functional
and monadic programming gets awkward or impure.) There may also be multiple
outputs and inputs at any stage in the process, an Arrow limits you to one
output and input vector making actual programming awkward. Forces the kinds of
composition you can describe.

~~~
danharaj
yikes.

------
jasonkostempski
Ubiquitous language.

------
inopinatus
title += ' (2002)'

