The latest flurry of bitching in the software development blogosphere is in reference to Joel Spolsky’s The Duct Tape Programmer, extolling the virtues of just getting some working code written without a bunch of pissing around with design:

Sometimes, you’re on a team, and you’re busy banging out the code, and somebody comes up to your desk, coffee mug in hand, and starts rattling on about how if you use multi-threaded COM apartments, your app will be 34% sparklier, and it’s not even that hard, because he’s written a bunch of templates, and all you have to do is multiply-inherit from 17 of his templates, each taking an average of 4 arguments, and you barely even have to write the body of the function. It’s just a gigantic list of multiple-inheritance from different classes and hey, presto, multi-apartment threaded COM. And your eyes are swimming, and you have no friggin’ idea what this frigtard is talking about, but he just won’t go away, and even if he does go away, he’s just going back into his office to write more of his clever classes constructed entirely from multiple inheritance from templates, without a single implementation body at all, and it’s going to crash like crazy and you’re going to get paged at night to come in and try to figure it out because he’ll be at some goddamn “Design Patterns” meetup.

You know what’s at least as hard as remembering to inherit 17 templates? Hunting down a bug in, or trying to add new functionality to, code made of 17-page methods that set 17 local variables in 17 different code paths through different if and case statements because it was slapped together by a programmer who either doesn’t understand design or modularity, or doesn’t care. And when I hear the phrase “duct-tape programmer,” that’s the image that comes to my mind. And where I’m from, we have a lot more of that variety of duct-taper than we have of what he’s pitting his idea of a duct-tape programmer against: a Rube Goldberg programmer, a particular variety of architecture astronaut that must be more common in his region of the globe than in mine, although I have seen them before. This kind overengineering makes a nicely flammable straw man if you’re arguing in favor of slap-it-together solutions, but if the choice is between that kind of overengineering and a no-design duct-tape approach, then get me the hell out of this business.

A few commenters here and there have made the point that Joel probably really meant to argue against unnecessary complexity, but just accidentally went batshit overboard into advocating shithackery, or else people are just misreading him. Because that’s actually a really good argument to make, and actually not far from my own principles.

Maybe this is just another case of what Giles Bowkett was talking about the other day:

the reason your first instinct is to write a blog post explaining to these people that they're just a bunch of fucking idiots is because they're just a bunch of fucking idiots. And it's not even that. They're not only just a bunch of fucking idiots. They're also just a bunch of fucking idiots who are reading your blog because they're too lazy to work and too dumb to win at Desktop Tower Defense or the eyeballing game. I can't blame you for talking down to them. They suck. But the thing is, they're not the only people reading your blog. There are a lot of other people reading your blog, people who are as smart as you or smarter, and as accomplished as you or more so. And when you tell that vast army of barely literate dipshits that the reason they don't pair program is because they're not as smart as you are, you are saying something true - but you are also telling these other people, these smart people, that the reason they don't pair program is because they are not as smart as you - and let me tell you something: they are. And they know it.

…in which the smart people, who get the difference between “not overdesigning” and “not designing,” are not the intended audience here. Maybe a bunch of us have just been sucked in by Joel’s attempt at a Giles-level troll. In which case, good on him, because it’s had the intended effect of drawing attention his way.

A good solution should make things easy, not make the programmer who wrote it feel like he looks smart for writing something complexificated. It looks dumb simple from the outside, but takes a certain amount of careful design thought to arrive at. In fact, it seems simple, and is simple to use, extend, and debug, because careful consideration was put into its design. So if that’s what Joel meant, then either he’s just not that good at saying things, or people are stupid, or both.

Folks ought to know who this Jamie Zawinski character is that Joel is holding up as an example of what he means by “duct-tape programmer,” and said Jamie Zawinski character is not at all the kind of programmer that the phrase “duct-tape programmer” evokes for me. So a big problem with Joel’s post is that phrase, which sounds like it means a programmer for whom duct tape is the only tool in his toolbox, rather than a programmer who knows when to use duct tape and when not to. The other problem is that he describes the duct-tape programmer’s nemesis as the kind of guy who would be found at “some goddamn Design Patterns meetup.” I’d go to things like Design Patterns meetups if they’d have one anywhere near me and/or I wasn’t constantly too broke to travel. And I wouldn’t be surprised, were I hypothetically to meet Mr. Zawinski himself, to end up in a pretty fascinating discussion on the subject of design patterns discussion with the guy. I’m betting he knows a thing or two about them. Oh, and then there’s the fact that Joel seems to be ragging on unit testing.

A good solution should make something easier, not make the programmer who wrote it feel like he looks smart for writing something complexificated. In fact, it seems simple, and is simple to use, extend, and debug, because careful consideration was put into its design. But knowing when to finish polishing the design, does not equal not bothering to put any thought into design.

Underdesign and overdesign each lead to their own brand of unnecessary complexity: underdesign leads to linear complexity, where you have long methods with a lot of state up in the air and lots of special-cases. Overdesign leads to a more dimensional complexity, where you have way too many classes/interfaces/modules where everything depends on everything else and the code is so abstract that it’s hard to find where functionality actually happens. Both kinds of code are needlessly hard for the next programmer, stuck maintaining or extending it, to follow.

This kind of thing is another reason why I haven’t been doing so much dev-blogging of late. The real distraction from getting working code designed, written, and shipped is getting distracted by these food-fights.

Update: Dare Obasanjo has another interesting take that seems to focus more on the phenomenon of gold-plating requirements. Which reminds me of certain past experiences where I was given a spec that had been written over the past year-plus, and told the deadline was three weeks away…

Update2: I’d found myself wondering what Zawinski himself might think of all this, if he’s even bothering to pay attention to it. Well here it is. Very cool.

Chuck Hoffman

Chuck Hoffman
I'm from Iowa. I sling code for a living and get pretty into it. I also do some fun things with experimental music and retro-tech.

Hello again

Couple changes to the ol' site here. First, I've moved it off Github Pages andonto the Dreamhost shared-hosting account I've had for ages...… Continue reading

SQL and NoSQL

Published on December 14, 2020

Notes on Dependency Injection

Published on December 11, 2020