Thursday, 1 June 2006
In response to yesterday's post on design by designing, colleague David came into my office today with Sherry Turkle's Life on the Screen open to chapter 2, "The Triumph of Tinkering," and said "You might like this." Wow, wow, he's right.
In the chapter, Turkle contrasts the "hard" (her word), abstract style of top-down design with the "soft," concrete, associative, bottom-up style that is characterized by Levi-Strauss's word bricolage:
[...] They tend to try one thing, step back, reconsider, and try another. For planners, mistakes are steps in the wrong direction; bricoleurs navigate through midcourse corrections. Bricoleurs approach problem-solving by entering into a conversation with their work materials that has more the flavor of a conversation than a monologue.Turkle cites Piaget's work in identifying how children learn abstract concepts such as numbers and counting from the concrete, not the other way around. She says that classic Western philosophy assumes that this concrete mode of thinking should be outgrown, but that this is not necessarily so: "Soft mastery is not a stage, it is a style."
Although our culture exalts the abstract over the concrete, in practice we might frequently (like children, per Piaget) use the concrete to deduce the abstract we nominally are working with:
Sociologists and anthropologists demonstrated that in scientific laboratories, there is a time-honored tradition of tinkering first and creating formal rationalizations later. Ethnographers of science showed that bench science often depends on a long, messy process of trial and error followed by the final, frantic scramble to rationalize the results. Similarly, close studies of the way scientific papers are written indicated that successive drafts cover the tracks of messy bricoleurs.Does this sound familiar? This makes me think that many people, perhaps most, work via this bricolage system of "let's see what this does." The Jeff Atwood quote I keep referring to about cleaning the cruft out of your code ("Ruthlessly delete code that isn't being used. That's why we have source control systems") indirectly addresses this -- why is the cruft there in the first place except as detritus from branches and paths that were tried and discarded?
Classical engineering has traditionally been less conducive to this style, if only because there are constraints on the cost and time of playing around with the design of, say, a bridge. Years ago, a programmer I knew, an EE, told me that when he designed circuit boards, he was a lot more careful about working out the design and hand-checking it; once you burned a board, that was it, and mistakes meant you threw it away. But with code, he figured you could just fix it and recompile. But even traditional top-down engineering design can yield to the style of bricolage, namely via the magic of computer simulation:
Now, playing with simulation encourages people to develop the skills of the more informal soft mastery because it is so easy to run "What if?" scenarios with the outcome.These days, this is as true for designing bridges and airplanes as it is for spreadsheets and Web pages.
When one contemplates the complexity of a system like the .NET Framework, it seems as if it would be impossible to create such an abstraction without detailed, top-down designs, to guarantee that the far-flung pieces would mesh together smoothly. But I wonder just how much real top-down design is actually required. I have no idea what the actual history of the framework is, but now I can imagine that it could have been developed from a comparatively small set of kernel ideas -- managed environment, language spec, compiler spec (all adaptations of prior art -- and then taken to the workbench for experimentation. Once a design emerged, the design could be reapplied to the various layers of the framework. Is one theory, anyway.
I recently edited an internal whitepaper that described the history of one of our products. Among the points that the author called out was that the product's history involved a long list of prototypes, which represented proofs of concept, experiments with alternative implementations, and many versions of subsystems.
What an eye-opener. I can stop feeling vaguely guilty that I make a short path between concept and experimentation, stopping only very briefly at the formal design. And in fact, this blog is a good example -- it was a bottom-up design, with new bits bolted on as I thought them up. As a finished product it's sort of a mess, but what I've really got on my hands is a prototype that just happens to be in production. Now that I've got proof of concept, I can rewrite the thing properly. Someday, that is.