Bryan Cantrill has now fleshed out his critique of Dreaming in Code that I recently addressed. I want to thank him for returning to the topic and giving it serious consideration. I’m going to respond at length because I think, after clearing away a lot of smaller points, we’ve actually found an interesting point to dispute.
As far as I can tell, Cantrill is now saying that the problem with Dreaming is that it starts from the notion that “software is hard” and then explains why it’s hard by exploring what makes it unique — and he would have preferred a book that started from the notion that software is unique and then explored why its uniqueness makes it hard. At some point this becomes pretty abstruse, and I’ll leave it to those of you who want to compare what Cantrill says with what’s in the book to weigh our different perspectives.
I do want to correct his statement that I “picked a doomed project” from the start, as if that was my intention, in order to support a pessimistic view of software. At the time I began following Chandler, it had high hopes and a lot of enthusiastic support. I chose it because I cared about the problems it set out to solve, I thought the people involved were interesting, and I thought it had a reasonable chance of success. 20/20 hindsight leads Cantrill to dismiss Chandler as an ill-fated “garbage barge” from the start. But that’s hardly how it looked in 2002. It attracted people with considerable renown in the field, like Andy Hertzfeld and Lou Montulli, as well as other, equally smart and talented developers whose names are not as widely known. Nor, even at this late date, do I consider Chandler in any way to be definitively “doomed” — though certainly it has failed to live up to its initial dreams. There are too many examples of projects that took long slogs through dark years and then emerged to fill some vital need for anyone to smugly dismiss Chandler, even today.
Also, I need to say that my interest in the difficulty of software did not emerge as some ex post facto effort to justify the problems that OSAF and Chandler faced. In fact, as I thought I wrote pretty clearly, it emerged from my own experience in the field at Salon, where we had our own experience of a software disaster at the height of the dotcom boom.
Finally, in substantiating his criticism of what he calls my “tour de crank” of software thinkers, Cantrill still doesn’t make a lot of sense to me. In the two chapters near the end of the book that depart from Chandler to explore wider issues, I discuss the work and ideas of Edsger Dijsktra, Watts Humphrey, Frederick Brooks, Ward Cunningham, Kent Beck, Joel Spolsky, Jason Fried and Nick Carr (in Chapter 9), and Charles Simonyi, Alan Kay, Jaron Lanier, Richard Gabriel and Donald Knuth (in Chapter 10). (Marvin Minsky and Bill Joy, whom Cantrill mentions, are each cited only in passing.) Anyone might view some number of these figures skeptically — I do, too — but cranks, all?
Anyway, these are side issues. It’s later in Cantrill’s argument that we get to the heart of a real disagreement that’s worth digging into. Despite the evident pragmatism that’s on display in his Google talk, halfway through his post Cantrill reveals himself as a software idealist.
…software — unlike everything else that we build — can achieve a timeless and absolute perfection….software’s ability to achieve perfection is indeed striking, for it makes software more like math than like traditional engineering domains.
And once software has achieved this kind of perfection, he continues, it “sediments into the information infrastructure,” becoming a lower-level abstraction for the next generation to build on.
Ahh! Now we’re onto something substantial. Cantrill’s view that aspects of software can achieve this state of “perfection” is tantalizing but, to me, plain wrong. He makes a big point of insisting that he’s not talking simply about “software that’s very, very good” or “software that’s dependable” or even “software that’s nearly flawless”; he really means absolutely perfect. To me, this insistence — which is not at all incidental, it’s the core of his disagreement with me — is perplexing.
Certainly, the process by which some complex breakthrough becomes a new foundational abstraction layer in software is real and vital; it’s how the field advances. (Dreaming in Code, I think, pays ample attention to this process, and at least tries to make it accessible to everyday readers.) But are these advances matters of perfection? Can they be created and then left to run themselves “in perpetuity” (Cantrill’s phrase)?
On its own, an algorithm is indeed pure math, like Cantrill says. But working software instantiates algorithms in functional systems. And those systems are not static. (Nor are the hardware foundations they lie upon — and even though we’re addressing software, not hardware, it’s unrealistic to assume that you will never need to alter your software to account for hardware changes.) Things change all the time. This mutability of the environment is not incidental; it’s an unavoidable and essential aspect of any piece of software’s existence. (We sometimes jokingly refer to this as “software rot.“) Some of those changes break the software — if not over a matter of weeks or months, then over years and decades. It is then, I think, no longer accurate to call it “perfect” — unless you want to take the pedantic position that the software itself remains “perfect,” it’s the accursed world-around-the-software that’s broken!
This, of course, is a version of Joel Spolsky’s Law of Leaky Abstractions argument, which I present at length in Dreaming in Code: “perfect” abstractions that you can ignore are wonderful until something happens that makes it impossible to keep ignoring them. Such things happen with predictable regularity in the software world I know. I don’t know how you can discuss software as if this issue does not lie at its heart.
The strange thing about this disagreement is that, as far as I can tell, Cantrill is — like the engineers I know a lot better than I know him — a hands-on kind of guy. And DTrace, the project he’s known for, is by most accounts a highly useful tool for diagnosing the myriad imperfections of real-world software systems — for navigating those trips down the ladder of abstraction that software developers must keep making.
All of which leaves me scratching my head, wondering where the world is in which Cantrill has found software of “absolute perfection,” and which programs it is that have achieved such a pristine state, and how they — unlike all other programs in existence — escape the creep of software rot.
[tags]bryan cantrill, software, software development, dreaming in code[/tags]
Post Revisions:
There are no revisions for this post.
As anyone who knows me will attest, I am very much a software realist.
Indeed, my realization about the perfection of software is actually a product of that realism: before I arrived in Solaris Kernel Development over a decade ago, I was convinced (largely because the Software Industrial Complex had taken great efforts to convince me) that software was fundamentally flawed, that bugs were endemic and that we were all sinners. I credit my mentor Jeff Bonwick (who went on to invent and develop ZFS) with disavowing me of that notion — not by dogma but rather by example. Simply put, Jeff has written a huge amount of perfect code — code that executes millions of times per day around the globe. (Jeff is so prolific in software that is used so widely that I say with confidence that Bonwick-written code will execute — somewhere — as a part of my commenting on this blog right now). Some of this code is small (Jeff’s mod-by-a-billion is legend), and some of it is large (kmem.c) — but huge tracts are indisputably and absolutely correct. As the years have gone by, I too have developed tens of thousands of lines of code that I would deem absolutely correct — code that now itself executes millions of times per day the world over, and shows absolutely no signs of being replaced. This is not to say that I always write perfect code (far, far from it), but I do always strive for it — and I believe that computer science will remain in its infancy as long as it is conventional wisdom that perfection is impossible. Incidentally, the potential perfection of software — and the chasm that separates the perfect from the flawed — is the subject of my chapter in “Beautiful Code”, a chapter that describes code that Jeff and I forged to perfection through one of the more mind-bending experiences of our respective careers.
Probably you have different ideas for the term ‘software’. I think it is unquestionable that there are algorithms and even bigger pieces of software (code) that are perfect in themselves. They accomplish the task they were build for (and incidentally even others) perfectly.
But this is only the inside view of software science. If you take software built from many components, having to cope with the outside environment the things look quite different…
It’s the dynamics of the world that put bigger pieces of software into another light. Suddenly requirements change and a component, though working perfectly, becomes obsolete because its preconditions are not met anymore.
(cf. Leaky Abstractions and the last Code Reads paper about changing requirements which made quite an impression on me)
BTW: compare the uses of the terms ‘software’ vs. ‘code’ in Scott’s article and Cantrill’s comment ;)
I think Johannes is making an important point here. Scott, you tend to be looking at the top layer of abstraction — that which interacts with the user. And indeed, this does change frequently, abstractions leak like sieves, etc. etc. I, on the other hand, (along with many other software engineers) think and work almost entirely in the domain of software/software interaction. Here, the air-tightness is part of the value proposition — just ask a VMware engineer what they need to do to assure that OS/2 works, or for that matter a Solaris engineer what we need to do to assure binary compatibility with a handful of infamous applications). I would therefore amend Spolsky’s law: for a well-defined abstraction, the leaks become sufficiently well-known and well-understood to themselves become part of the abstraction — after which point the abstraction holds fast. Beyond this point (and many, many abstractions hit this point), perfection becomes attainable…
Thanks, Bryan and Johannes — I think we’re getting to some important distinctions.
Plainly, I need to hie myself to Beautiful Code and read Bryan’s chapter. (And more, I’m sure.) I will do so and then perhaps post more on all this…
Scott, A word of warning that that chapter is a bit… dense. But hopefully the point regarding software perfection (and the knife-edge that separates it from sewage) will shine through. Also, I have followed up a bit more in the comments of my initial response — in particular, marking perhaps the only time that Super Mario Kart has been used to make a point in a philosophical debate about software. ;) A longer blog entry on all of this is called for; hopefully I’ll find time for that sometime over the next week…
Bryan: thanks for the excellent analysis. The next question becomes: where does the value of software come from? Surely much of it comes from what you call “the user.” Software that interacts only with hardware can give what we might call direct value (and might fit the paradigm you prefer), but software that interacts only with other software is a means to an end. It derives value from partially enabling the software that people use (that value can be very high due to leverage and scale, of course).
I was disappointed with Beautiful Code because the majority of the entries fled the messy world where value actually arises for the tidy world where APIs can aspire to elegance. Worse, a large number of them more-or-less took as a postulate that “beautiful” == “fast”.
Like hundreds of thousands (?) millions (?) of other software developers, I write programs with human interfaces. Those programs would not be possible without the work of systems giants such as yourself, and speed is an occasional issue, but I have found the worship of internal elegance (and speed) in the culture of software development to be unhelpful, while the issues that Scott discusses in DiC are pressing everyday concerns for me.
Perhaps the biggest obstacle to developing coherent theories of software development is the sheer diversity of the work?
Sam,
I think you’re raising some good points here, but I definitely think that software that interacts only with other software has value — considering that that includes every compiler, every operating system, every database, every virtual machine, every app server, etc. Or rather, if it doesn’t have value, there are a ton of people who are paying too much for it. ;) And while it is true that ultimate value is derived from users’ interactions with the system, those interactions need not be explicit — and frequently aren’t in companies for whom IT is a core competency. For example, my interactions with FedEx consist of giving them a package, and perhaps checking a website a couple of times — but there’s a tremendous amount of deep, unseen, valuable IT that makes FedEx happen and happen efficiently…
Bryan: agreed 100%.
I wonder if a decent model for “software engineering” might be something like the sciences, where a broad hierarchy:
math -> physics -> chemistry -> biology -> …
exists but doesn’t strangle the culture of the lower branches. All “field biologists” like me need some familiarity with the “physics” invented by you and your peers, and ultimately depend on it in various ways. “Biological physics” — domains where the algorithm is the heart of the user tool, such as search — certainly exist. But the many programmers doing the equivalent of studying polar bears or developmental genetics are IMHO not helped by a professional culture which exalts the terse, high-performance, hardware-centric systems algorithm above all, any more than field biologists are helped by exhortations to do better mathematical analysis of quarks.
Another way to look at it: in my mind, Page and Brin are arguably second only to Berners-Lee in their contributions to making the Internet a public tool. Yet in the professional discourse I follow they receive many times more attention than he does. Money and contemporaneity surely cause some of this, but it seems noteworthy that in one case where the landmark breakthrough at the application level provides the foundation for a big deal algorithm, we as a profession have flocked to them as heroic leaders, while mostly ignoring him.
Sam,
Interesting comparison and taxonomy — and it meshes well with my notion that software is still extraordinarily young. (We are still in the era of “physicks” and “natural philosophy” to continue with your science analogy.) A new model is certainly needed, and I believe that truly coming to grips with the uniqueness of software is a prerequisite — and that means a broad-based understanding of notions like the perfection that software alone can achieve. (By the way, it is my belief that this will happen — at the latest — when humanity collectively realizes that the software upon which it has become inextricably dependent was largely written by dead engineers. This isn’t true today — by a long shot — but it’s hard to see how it won’t be true a hundred or two hundred years from now…)
You wrote “There are too many examples of projects that took long slogs through dark years and then emerged to fill some vital need for anyone to smugly dismiss Chandler, even today.”
I can’t think of any examples. Maybe NeXTStep, but even that didn’t slog along for years unreleased. Vista had a long slog, but it didn’t emerge to fill a vital need. Chandler is an example of a project that will probably be irrelevant if it is finished and released — a modern “Soul Of A New Machine.” Projects that don’t move at least a little faster than the computing ecosystem as a whole are pretty much doomed.
One more thing. In this list which names don’t belong? Edsger Dijsktra, Watts Humphrey, Frederick Brooks, Ward Cunningham, Kent Beck, Joel Spolsky, Jason Fried, Nick Carr, Charles Simonyi, Alan Kay, Jaron Lanier, Richard Gabriel and Donald Knuth.
Obviously a lot of important names are missing, but what the heck is Joel Spolsky doing there? And Jason Fried? Their contributions are ephemeral or insubstantial by comparison to Knuth, Dijkstra, and Kay. If you think Joel’s “law of leaky abstractions” is an important new concept you should read his sources: Glenford Myers, Edward Yourdon, Brian Kernighan, and Steve McConnell.
Hi, Greg — You’d have to look at those chapters to see why I included who I included. I make no pretense to offering an exhaustive study or a reference work. Some of the people I chose to discuss not because they were the first or the most probing but because they articulated ideas in an accessible way. Joel and Jason fall into that camp, for me. I’m very familiar with Yourdon, Kernighan and McConnell; less so, Myers — thanks for the reference.
As for examples of projects that dropped off the radar and then returned, well, the biggest example is the software I’m using right now — Firefox. I use both that and NeXT as examples in the book. The Web itself spent 3-4 years as a project with very limited participation until Mosaic introduced it to a much wider public. And so on. The larger point to me is that the life cycle of software isn’t a linear sort of thing. I totally agree that in general, most successful projects stay a little ahead of the various cycles that govern the field. But sometimes a project falls so far behind one turn of the wheel that it ends up a little ahead of the next. Admittedly, this is not common. But it happens!
A previous discussion from 2004 on perfect software,
http://blogs.sun.com/bmc/entry/the_economics_of_software#comment-1093905190000
I haven’t changed my mind yet..
Taking Euclid’s theorems by way of example, certainly the GCD algorithm has an existence as a glorious immutable truth (given of course the usual Godelian caveats). But it also has many instantiations, expressions in mutable media, most of which are now defunct. The Alexandrian scroll itself may have had transcription errors or lacunae. The existence of the immutable truth doesn’t help the scribe who is trying to compute something based on the scroll with its incomplete or imperfect expression of the truth.
When we deal with software, we’re not usually at the ‘immutable truth’ level. A few brilliant coders are, but, lackaday, most of us who toil at this particular coalface are not there. We’re dealing with the Platonic shadows of their brilliance. From our perspective, calling software ‘perfect’ looks like a category mistake: and giving databases as an example of the bedrock stability of software, verges on the ludicrous. Certainly there are thousands of installations of large databases processing billions of calls every day, which is pretty damn good software. There are also spectacular disasters in every database system known to man, at wholly unpredictable intervals. This is not perfection, nor do I expect to live to see it.
I wouldn’t put Joel Spolsky in the same sentence or chapter as the others. Granted, he does explain some concepts well, and is fortunate to have most of the Web 2.0 crowd as his fanboys. But I haven’t read of any great software output or idea from him yet. Most of the other people on your list would find it insulting or amusing.
Bryan: Your software/software interaction is what’s assigned to beginners (like rendering engines in 3D games, game engines, protocols, scripting languages and parsers). You can specify constraints on data and be done with it. Hand the spec over and let the programmer plug away. All that’s required is knowledge. In the book, it talks about the server project handled by one person. The reason it had less problems is exactly because it doesn’t deal with the user. But that would have been a really boring story. That’s not where the problems are.
Without software that interfaces with users (or real life events), the software/software interaction code that you’re writing may be perfect, but ultimately useless. If your code is used at all, it’s because of those programmers that write the software that interacts with users.