Go forward in time to July 2012.
In my last post, I said that I changed the Pattern Template page in the wiki to be more like a part of an evolving language, and less like a functional specification for a widget or group of widgets. Let's see what this means.
A functional specification is an awesome thing to have for when you are absolutely sure that you know the right way of building something. It's an extremely detailed plan, and the plan was hopefully written by someone who really knows what they are doing — by someone who has built that thing before a few times.
With software we often don't have such luxury — the "written" part if you don't have a spec, and the "by someone who has built that thing before" if you have no mentor or if you are writing something that hasn't been done before.
In that case, the most you can hope for is to look for nuggets of experience from people who have built similar things, and to look at the materials you have and the ways you can combine them to see if they are fit for your purpose.
There is a theoretical foundation for all of this, called...
During my talk at the Desktop Summit from last year, I briefly presented pattern languages and form languages. Please forgive me for recycling some material from there.
Look at two architectures and their differences:
China and Japan
Mostly wooden structures. Walls are wood and/or paper.
Roofs are sloping and curved, and they have clay tiles.
Each row of tiles has a decorative cap at the end.
Roofs don't have diagonal beams to support them; instead, there is a sophisticated system of brackets that “sprout” from the columns.
Walls are wood and clay, or brick and stone.
Glass windows. Note the blown glass on the old/rightmost window, vs. plate glass on the more modern bridge on the left.
Roofs are sloping and straight. They sometimes have clay tiles; they often have wooden shingles.
Roofs have diagonal beams to support them.
Despite these differences, both Germany and China/Japan had private houses, public buildings, kitchens, sleeping places, gardens, etc. - but they were built differently. They share the same functions and support the same social interactions, but their construction is different.
Quoting Two Languages for Architecture, by Nikos Salingaros:
The pattern language is a set of inherited tried-and-true solutions that optimize how the built environment promotes human life and a sense of well-being. It combines geometry and social behavior patterns into a set of useful relationships, summarizing how built form can accommodate human activities. The form language, on the other hand, is strictly geometrical. It is defined by the elements of form as constituted by the floors, the walls, the ceiling, the partitions, and all the architectural components or articulations, which together represent a particular form and style of building.
Now we can compare widget toolkits in an analogous way. Here are two familiar text editors:
If we were to extract a pattern called "multi-file text editor for programmers" from Kate and Gedit, we could look at what things work well — the things in these editors that the intended users appreciate and feel comfortable with. That big pattern could end up being composed of sub-patterns like "sidebar shows open files", or "cursor position as line/column numbers" (useful to locate compiler errors; not so useful in a word processor where paragraphs flow), or "highlight the text line being edited".
Those patterns would tell you why they refer to useful features; why their composition into the "text editor for programmers" pattern creates something truly comfortable.
However, we can see that the form language is different. Kate uses Qt and KDE's widget libraries; Gedit uses GTK+ and Gnome's paraphernalia. You can compose the pieces in each of those universes in very well-defined ways, but you can't build something out of both, at the same time, without doing something that Miguel would call "professional gymnastics".
A form language is about materials and how they can be shaped, joined, and combined together. Buildings with a wooden structure can be built in the German style as above (Western joinery; diagonal beams, wattle exterior walls, a certain set of proportions...), or in the Japanese style (Japanese joinery, proportions relative to standard-sized tatami mats...). But wooden buildings in general, regardless of style or tradition, will have to respect the properties of the material itself. Wood shrinks and expands with changes in humidity; you have to take that into account. Some types of joints are better than others depending on the direction of the stresses that the joined pieces will take.
And so it is with widget toolkits. GTK+ lets you compose widgets via containers in box or tabular layouts. Those layouts can do some things easily (e.g. deal with changes in widget size due to text translations), and they make other things annoyingly difficult (e.g. ensure that widgets align to a certain line when they are not direct siblings in the container hierarchy).
Definitely; I have digressed!
The point I'm trying to make is that form languages — the things that materials let you do according to their properties and to the traditions/standards for using them — need to be tied to pattern languages in order to build good things; in order to have an adaptive design method, as Salingaros calls it.
This is why I don't think a pattern language should try to standardize things like keybindings, widget positions, or particular widgets themselves. A pattern should contain the aspects that make a solution good for humans; the form language can standardize all it wants based on the materials to which it refers. We can certainly reference known forms from the patterns themselves, and we can even share parts of the form language across "materials": if you are writing a zooming view in GTK+ and one in Clutter, they can both use the same "zooming" pattern and the same standard keybindings from the form language, but they *will* have to use different idioms from the toolkits themselves.
Hopefully I'll have examples about this as I untangle some of the extremely detailed patterns that we have now.
I did some changes to the Pattern Template page on the wiki. This is the gist of my changes; I'll explain them below.
1. Added a "confidence level" line, which can be */**/***.
2. Added sections for super-patterns and sub-patterns. This lets us build the pattern language recursively up or down.
3. Make the pattern template look more like a part of an evolving language, and less like a functional specification for a widget or group of widgets.
I'll quote a bit from the introduction to A Pattern Language, which should help explain these changes. Boldface is mine.
In short, no pattern is an isolated entity. Each pattern can exist in the world, only to the extent that is supported by other patterns: the larger patterns in which it is embedded, the patterns of the same size that surround it, and the smaller patterns which are embedded in it.
This is a fundamental view of the world. It says that when you build a thing you cannot merely build that thing in isolation, but must also repair the world around it, and within it, so that the larger world at that one place becomes more coherent [...].
Each solution is stated in such a way that it gives the essential field of relationships needed to solve the problem, but in a very general and abstract way — so that you can solve the problem for yourself, in your own way, by adapting it to your preferences, and the local conditions at the place where you are making it.
For this reason, we have tried to write each solution in a way which imposes nothing on you. It contains only those essentials which cannot be avoided if you really want to solve the problem. In this sense, we have tried, in each solution, to capture the invariant property common to all places which succeed in solving the problem.
But of course, we have not always succeeded. The solutions we have given to these problems vary in significance. Some are more true, more profound, more certain, than others. To show this clearly we have marked every pattern, in the text itself, with two asterisks, or one asterisk, or no asterisks.
In the patterns marked with two asterisks, we believe that we have succeeded in stating a true invariant: in short, that the solution we have stated summarizes a property common to all possible ways of solving the stated problem. In these two-asterisk cases we believe, in short, that it is not possible to solve the stated problem properly, without shaping the environment in one way or another according to the pattern that we have given [...].
In the patterns marked with one asterisk, we believe that we have made some progress towards identifying such an invariant: but that with careful work it will certainly be possible to improve on the solution. In these cases, we believe it would be wise for you to treat the pattern with a certain amount of disrespect — and that you seek out variants of the solution which we have given, since there are almost certainly possible ranges of solutions which are not covered by what we have written.
Finally, in the patterns without an asterisk, we are certain that we have not succeeded in defining a true invariant — that, on the contrary, there are certainly ways of solving the problem different from the one which we have given. In these cases we have still stated a solution, in order to be concrete — to provide the reader with at least one way of solving the problem — but the task of finding the true invariant, the true property which lies at the heart of all possible solutions to this problem, remains undone.
During the 2010 User Experience Hackfest in London, which I was a doofus not to attend, there was a lot of work done in planning the new Human Interface Guidelines for Gnome, and in particular turning it into a pattern language.
I have been doing some research on best practices for constructing pattern languages.
1. You start by exploring the space you want to pattern-ify, gathering little nuggets of information which seem obviously true, that feel good to yourself:
I really like this quiet spot where I can sit in the garden.
At my friend's house there is a convenient shelf by the front door, where he leaves his keys and wallet.
This window manager, that snaps edges of windows when you move them, feels just right.
Interactive search in Emacs is so fast and convenient.
You may not know why they feel good, but you are sure they do.
2. You try to figure out what it is that makes those things so pleasant. Are there other factors that contribute to them? Are there things without which they just wouldn't be complete? For the examples above:
The quiet spot is not too shady and not too sunny. I can lean back on a wall or the back of a bench. I can look at flowers or fruits from the tree that shades me. Somehow it feels safe to be here.
Not only his keys and wallet are there; in the house they seem to use that shelf for things they shouldn't forget when they go out the door next day. They have a little notebook to leave messages to each other. The shelf is not too big so it can't accumulate too much chaos. The shelf is at waist height, so you don't have to bend down to put things there.
Windows snap to each other's edges, but I don't have to fight a window loose if I want to move it away; it unsticks at the right time. The mouse never loses the window even if the window sticks. Resizing also snaps, making multi-window layouts quick and easy.
As soon as I hit the Search hotkey and start typing, the first textual match is highlighted. All other matches on the window are highlighted in a different color. I can hit the hotkey again to go to the next match, or go back with another key. I get told unobtrusively when the document ends and the search wraps around.
3. You recurse down. Are those things made out of smaller things?
Outdoor seat spots in general. Private spots in a garden. Fruit trees in special places, not just thrown around. A wall behind your back. These are all smaller patterns, each with their own reasons and conditions.
Waist-high shelves seem convenient not just at the front door, but in other high-traffic areas of the house as well. And that's it (atomic pattern).
Snapping to convenient points when dragging objects in general. The actual fine-grained behavior of snapping: do things "stop" when you reach the right spot, or do they "magnetize" when you are near the right spot? Can you make fine adjustments around a spot where things would normally snap? This seems to be a more general pattern than just for moving/resizing windows.
Quick access to frequently-used functions (the Search function). Highlighting relevant content. Easy navigation in a big document. Ease of getting into and out of a transient mode (there is no Search dialog that you need to open, and then close when you are done). Each of these seems like it could be a pattern for functions other than Search.
4. You recurse up to see if there are larger patterns that use your prototypal little pattern.
A garden should certainly have a quiet spot, and other things as well — ponds, aromatic herbs/flowers, bird baths, etc. So the "quiet garden spot" becomes a sub-pattern for many kinds of gardens. A public formal garden (which could use a maze), a private garden in a house (which could use water captured from your roofs), etc.
An entrance room in a house will benefit from a waist-high shelf, plus an ample door (for moving in furniture and big things), a coat hanger, things like that. Adapt it to the local conditions: do you need a shoe rack for dirty shoes? Do you have some sort of window on the door to see who is knocking?
While a window manager will benefit from well-implemented snapping, it will help to detail the actual behavior that snapping should have in various situations. Snapping shapes in a drawing program. Snapping to automatically-generated guidelines like in Google Sketchup. Snapping to chapters in a DVD when using the Seek bar. Snapping to commonly-used font sizes in a size slider.
If there were a pattern for document navigation, an Emacs-like search function would be a good idea — plus other things, like a sidebar with an outline for textual documents, or page thumbnails for a page layout program.
These are the articles on writing pattern languages which I found the most useful:
Lingua Francas for Design: Sacred Places and Pattern Languages, by Tom Erickson. He describes an earlier study where the town of Manteo, North Carolina, USA, made a list of important places in their town and the social interactions that happened in them. This helped them take really good decisions on how to improve the town, preserving what was good, and strengthening what was unloved. After this story, Erickson describes how this can be applied to interaction design. (By the way, Tom Erickson's page of Interaction Patterns is a catch-all of awesome.)
The Structure of Pattern Languages, by Nikos Salingaros. "This paper describes how to validate existing pattern languages, how to develop them, and how they evolve." It has some very nice diagrams of how patterns link to each other in a graph...
... how they form a hierarchy with patterns at different levels of scale, from the big ones to the small ones...
... and how patterns on one level help define a new pattern on a higher level.
Seven Habits of Successful Pattern Writers, by John Vlissides. Don't get put off by the *cough* clever title, this is actually quite good. It is a "don't panic" set of recommendations: get concrete early, iterate and test everything, take time to reflect.
Fine Points of Pattern Writing, by Richard P. Gabriel. It's a presentation on stylistic aspects of written patterns, technical writing, and presenting a coherent story with a pattern language. You can tell Richard is a poet by the detail he pays to wording.
Go backward in time to May 2012.Federico Mena-Quintero <firstname.lastname@example.org> Tue 2012/Jun/12 11:43:45 CDT