The Duct Tape Programmer
theodp writes "Joel Spolsky sings the praises of The Duct Tape Programmer, who delivers programming teams from the evil of 'architecture astronauts' who might otherwise derail a project with their faddish programming craziness. The say-no-to-over-engineering attitude of the Duct Tape Programmer stems not from orneriness, but from the realization that even a 50%-good solution that people actually have solves more problems and survives longer than a 99% solution that nobody has because it's in your lab where you're endlessly polishing the damn thing. Like Steve Jobs, Duct Tape Programmers firmly believe that Real Artists Ship."
...also protect you from sellers of snake oil and fake gems?
Ezekiel 23:20
Agile, scrum, patterns, unit tests, etc.
.
Interesting ideas, but can anybody show me *any* significant, quantitative, comparative proof of improved ROI?
.
Software is about money guys.
Please do not read this sig. Thank you.
my employer knows I can whip out a fast 4,000 line (but ugly, no artistic talent) web portal or e-commerce app in a month when it should be a 20K line project done by a team, so that's what we do. dangerous I think, we handle real money with that shit.
The "duct tape programmer" is just as dangerous as the "astronaut architect".
What distinguishes good architects from these fools is this:
A good architect is someone with the experience to know when to cut corners and when to enforce rigid discipline.
You can't measure Synergy man, you just have to feel it!
I only look human.
My mother is a halfling and my dad is an ogre, so that makes me an Ogreling
I agree with most of Joel's post. What bothers me with this kind of thing is that there are a lot of idiots out there just waiting for an excuse for their poor standards. For every real Duct Tape Programmer there are ten buffoons who will now take that label for themselves. But hell they shoudln't be hard to spot.
I'm plagiarizing a point I saw on Reddit and I'm too lazy to find the original article, but I agree with the author of it: there doesn't have to be a choice between "crappy duct tape" programming and "crappy over-architected" programming. A decent programmer can get both: a small program that does its job well, AND can be extended in unplanned-for ways for new functionality.
One month to write and years to debug and get right.
Wow....praises for everything that is wrong with programming.
I believe in a 100% good project, and somewhere around 97%+ good project. If it can't be delivered, then you're not smart enough, or it's not possible.
Of course, I think he means something along the lines of industry software.
I work in the auto repair industry as a system administrator. We have 20 industry specific programs. They fall into two categories:
1. Programs developed by companies within the industry with no real programming experience. IE. Auto Shop gets smartest guy to learn how to program - builts program...these are the programs that are 50% good. Poor programming practice, unstable, but overall, on a good day, works well enough to increase efficiency beyond that of a pen/paper.
2. Programs developed by professional programmers with no industry experience. These programs are polished, stable, run fast. The problem is, since the programmers have little or no industry experience, there is an obvious disconnect in the work process within the program. This results in features we don't need, or things we need that are absent.
Overall, as a system administrator, #2 are better for me, because they work. #1 are better for the workers themselves.
We have one program that "tracks changes" by polling every file on the hard drive constantly. Starts at the top and works through every file and starts again. We have a server dedicated to this, chews up a 4-core processor. When asked about it, they said there was no other way to do it...uh huh...this is the #1 approach.
They don't even hold a candle to gaffer tape programmers.
Why is it that whenever I read an article by Joel I feel like I'm being talked down to?
is the duct tape manager
trying to hop in his chair to the phone, arms bound to the armrests with duct tape, screaming MMMMPH MMMMPH through the glorious dull shiny grey of...
what were we talking about?
intellectual property law is philosophically incoherent. it is your moral duty to ignore it or sabotage it
Scenario 1: Your client needs an application that will accept data input for approximately 400 different forms, allow those forms to be validated using some rules that are simple and others that are very complex, and put those forms through a fairly standard work flow.
Scenario 2: Your client needs an application that has 5 different forms used for very different purposes whose data will be processed in very different ways.
In Scenario 1, you had better do some engineering up front to save you from custom coding the parts of those 400 forms that could have been "over-engineered" into templates, base classes, and interfaces.
In Scenario 2, it makes sense to duct-tape.
I often don't like the choices people make, but I like the fact that people make choices. That's why I'm a conservative.
Curious that JWZ and his time at Netscape were particularly lauded here.
It's quite likely I'm being a bit snarky here... but Netscape lost the browser wars just a few years after they hit it big. And the core code of Netscape Navigator was bad enough that they eventually abandoned it around 1999 with the start of the Mozilla project.
Now don't get me wrong, it was only through the herculean efforts of guys like JWZ at Netscape that allowed them to ship a product at all. And certainly it made him and some of the founders a lot of money, which is a valid measure of success in business.
But to point to that particular code base as an example we all should follow? I don't think so. Certainly, choosing C++ then (or now in my opinion) is a mistake. And I've definitely seen people get overly rambunctious with architecture... especially in the Java world. But I think that's mostly the result of programming languages sucking as much as anything else. That and most people just aren't that good at design. Mostly meaning that when they've come up with a bad design themselves, they can't admit that and then really do what it takes to try and fix it. Of course, in the business world there are always severe time / money constraints, so that makes it real hard. And that's when not having unit tests hurts more... because it is harder to make significant changes to the code and have some assurance you didn't make mistakes.
Duct tape programmers may be invaluable tools in Joels world of overpervasive market economy and the corporate, but in some areas of application duct tape just does not cut it. Mission critical applications, like those used in health "industry", expensive satellites and other kind of space vessels, tunnel digging machines and what not - everything that just cannot fail - will not really benefit from Joels so cleverly coined "duct tape programmer" character. Not sure if Joel included these areas as applicable for the "duct tape programmer" attitude, but I just wanted to say I don't think they are. Let duct tape programmers develop Photoshop, and all those benemoths of software that runs slower the faster machines we throw at them, occupy more space for the same set of features and so on and so on - probably nobody notices that anymore, as we all are sworn to content. But the few areas where software quality makes it or breaks it, Joel is off the mark, IMO.
I'm completely with you on that one. What Joel is effectively lobbying for is what I've long termed "Shit and fix" coding. You write something dirty but quick to meet the minimal needs of the project. You have non-existent testing, inconsistent modularization, and a maintenance nightmare that crops up every 6 weeks as the application breaks or users request a functional change.
After a few years the application is such a mess and original knowledge sources are so far gone (documentation? what's that?) that the only option for the company is to recreate the application from scratch. Blowing tens if not hundreds of thousands of dollars on fixing the pile of crap that has been building up.
There is definitely a balance between over engineering and minimal effort. I've seen efforts to go in both directions. If I had a dollar for every time I saw someone put IO operations on the GUI thread in Windows, I'd be a rich man. But at the same time, I've seen people design data abstraction layers that turn a 3-tier application into a 7-tier "solution".
-Rick
"Most people in the U.S. wouldn't know they live in a tyrannical state if it walked up and grabbed their junk." - MyFirs
I manage a small team of programmers. When I first started, I 'inherited' a developer, let's call him Crufty Joe, who had worked at the company for 20 years and had developed financial and hr routines on the old mainframe and spiffy new oracle apps system. Joe had developed a lot of code, but he was always having to perform updates and corrections...
Why? Because he was a duct tape programmer! He always got it done by the deadline, but then he spent 75% of his time maintaining the huge pile of cruft that he had left in his wake over the years.
Well, Joe retired and I had to place two developers on his projects for the next year just to clean out all of the old '50% working' routines, in some cases we just tossed the exisiting work and started from scratch. What was really frustrating about this was that the Oracle apps have a huge, nearly incomprehensible, but extremely useful architecture that he did not even bother to leverage, but just wrote around.
This story acts like stopping to think about what you are doing means that you are going to implement huge, stupid architectures, but in reality he is just making excuses for being a sloppy hack. I feel damn sorry for anybody that has to support this crap in the future.
Wherever You Go, There You Are
Shipping is easy. Any idiot can whip something together that solves a problem, ships on time etc. That is rarely the issue. The issue is doing it in a fashion that will scale, be extensible, modifiable, understandable, high performing... the list goes on.
Given enogh time, any idiot could also make a system that is polished and architected to the point where it is fast, modifiable and extensible, and long overdue.
Bottom line: the whole skill of this business is delivering something that is architected enough while still meeting the deadline. In my experience, the necessary timeframe to deliver something long lasting and well architected is around five to ten times the time it would take to just solve the problem (tm). Of course many business exist today because they managed to release something to make money. The biggest mistake of many startups is probably polishing too much and not releasing early enough. The biggest mistake of those who DO make it past the first release is to not throw the first solution away and start over if it was something duct taped together.
is Release 2.
My respect for him ratcheted down quite a lot. Yes, you must ship (who knew?). That's what milestones and deadlines are for, so keep overarchitecting and feature creep from occurring. However, I would NEVER want to let a "Duct Tap Programmer" near any project that I would ever have to modify, maintain, or extend. You know, something that isn't completely trivial.
I don't know what kind of crack I was on, but I suspect it was decaf.
I don't think this guy ever worked with any software engineer with any significant amount of experience. Or maybe he just works with people that suck as software engineer.
The typical evolution towards wisdom in Software Engineering goes like this (simplified):
At best what the guy in the article is calling "duct-tape programmer" is somebody past the 3rd transition only and what he calls and "astronaut architect" is somebody past the 2nd transition only.
I would hardly call a junior designer type "architect".
Always write code as if the guy who has to maintain it is a sociopath who knows where you live.
Calm down, they just run out of duct tape.
The duct tape programmer represents those developers that "just want to do it".
Their comfort zone is coding so they really what to start coding and "see things moving" asap. They'll work really hard, go down coding/design dead-ends and back, re-write whole sections of the code, work long hours and eventually deliver something .... that doesn't do what's actually needed (say, because a requirement wasn't double checked with the users, or the format of the data being exchanged with some other system wasn't properly hammered-down with the guys developing the other system or the chosen technology can't deliver the needed performance or any other of a million reasons). Crazy last minute adjustments and re-writtings follow and what comes out is a "not exactly what we needed app", from start held together with spit and chewing-gum.
Compare this with somebody that works smart and takes some time to prepare up front before starting coding (things like checking requirements, hammering down message formats, making sure the chosen technology can deliver) and at the end delivers something that not only works but also does what is needed and, just as important, keeps on working without requiring constant baby-sitting.
Well, I am - more or less - a duct tape programmer, coming from the embedded field of work.
Two months ago I took a Java training course, never bothered to learn the language right before. One of the students at the training was a woman in her mid-forties, former quality assurance, with a wish to develop software. Last time she has written real code by her self was at the university 20 years ago. After that she only has read other people's code, tested it, found bugs there.
After a couple of days of introducing Java and the whole OOP concept, the teacher gave us some exercise. I don't remember what it was exactly now. What I do remember is that I hacked some code together, not bad at all, with lots of features, much more than it was needed, but since I was so fast, I was very smug about it.
Then the teacher showed my code to all students first, said it was a pretty nice solution with some tricks he never had thought of. Then he showed us her code. That woman had neatly written the task down first, planned everything carefully on paper and then implemented it, with lots of comments and an extremely clean and well-engineered code. Her solution wasn't quite as sophisticated as mine, but the code was so much more readable...
The teacher said that such code was the way to go, and as smug as I was over my solution, I had to admit that her job was much better done. Sure, features are great but clean, maintainable and well-planned code trumps in long term.
"It's such a fine line between stupid and clever" -- David St. Hubbins, Spinal Tap
I'm working on slop-bucket code like that now that I inherited. It's frustrating, but having seen this odd phenomenon before, I realized something: Reactionary programmers develop better reactionary skills to compensate. Sure, they are fixing things often, but they are also fairly proficient at digging around in spaghetti and fixing it. Cleaner approaches atrophy one's skills at ad-hoc repair such that you *have* to rely on cleaner approaches. You become a less-skilled trouble-shooter.
I'll still take the cleaner approach over the ad-hoc approach (barring over-engineered red-tape code), but for some reason the ad-hoc approach is "good enough" in the hands of a good ad-hoc-er. It's an odd thing to witness.
I've also seen another guy type (keyboard) at 100-miles-an-hour as he kept reinventing the wheel. He expressed no interest in further automation and abstraction to simplify the process. I think he had a kind of A.D.D. that made him want to be moving all the time. It's almost as if the guy with tweezers can mow the lawn almost as fast as a guy with a lawn-mower because he tweezed so damned fast. It may work as long as he doesn't get repetitive motion injuries.
I'm not endorsing ad-hoc-ism and mass repetition, but only saying that the down-sides may not be as big as one would think. Those who engage in the practice are often determined and resourceful survivors who find a way to work with what they know and are good at.
Table-ized A.I.
Okay I will give you that- not unit testing is pretty stupid. I guess there is a happy medium between the astronaut and the duct tape guy.
love is just extroverted narcissism
It's called the video game industry. That kind of methodology works there because you're generally not going to be maintaining the code base once it ships. There are three types of people you need to have a viable and successful team:
1. People who can do abstractions, design, and estimation.
2. People who can implement those designs (Duct Tape programmers are perfect for this).
3. People who can do a little of both.
I call bullshit on any one of these groups pointing the finger to the other and saying, "My way is best". If you had an office of nothing but designers you'd have a different but similar set of problems.
I've seen projects run only by duct tape programmers fail miserably in the field when extensibility and maintenance are required, but when we added a designer to that same team and rewrote the same project we delivered a bug free implementation with a 10 fold performance increase, and no significant bugs. That wasn't magic, it was just taking the time to do the damn thing right (and no more time than that).
Microsoft's problem is probably that they are a weird combination of duct tape programmers and architecture astronauts. They create a massive complex architecture which they can't complete and then ship it. Google seem to be able to deliver. But they use Java, Python and C++. All heavily OO. I wonder if they use templates, multiple inheritance etc.
I keep seeing this "good enough" meme going around. At a company meeting, recently, management was espousing the same crap.
I can only hope that these people are plagued with "50%-good" products. 50%-good tires, that blow out ocassionally, causing an accident. Maybe Joel would like some 50%-good surgery, or a 50%-good pacemaker. How about getting to fly in 50% good airplanes for the rest of his life?
I'm not surprised that most of this bullshit is coming out a culture in which Walmart was able to become the success it has. We needed something for a weekend project recently and bought the materials from Walmart, because it was closest. What poor quality crap. It'll all need to be replaced in a year, contributing to landfill and wasted resources. I'm not going purchase from Walmart any more, and I'm not going to spend money on half-baked, crap-quality software, either.
Word gets around about quality. It's the American auto-maker's nightmare right now. Ford, Chrystler, Chevrolet... they're all struggling to reverse decades of built-up public perception about poor quality, even when some of them are actually making fairly decent cars right now. It isn't quite the same with software; Microsoft has been making crap software for, well, ever, and they're still dominant. But I think that if you take the monopoly factor out of it, software companies *do* suffer from delivering half-assed product to their customers.
Can you emulate what JWZ did? Sure. Does that mean you'll be successful? I doubt it. THis discussion isn't about unit tests or dev methodologies in the traditional sense. It's about guys that threw that stuff out and achieved success in spite of it. It's much more subtle than being a hack that get's stuff "done." It's about being a hacker that get's stuff Done (with a big D) One you want on your team, they are rare individuals that can guide you towards riches, the other? Well you've probably got them around and they're probably paid too much and they actually cost the organization over the long term rather than help it.
My idea is that a good duct tape coder does mostly procedural code
So suddenly people who favour an OO or functional approach can't be "duct tape" coders? Interesting, particularly since a good procedural coder does the exact same thing as a good functional or OO programmer: the break the code down into small, testable, reuseable modules that are highly cohesive and weakly coupled. Whether you do that with procedural modules, objects, or functions is entirely irrelevant (though some paradigms make certain types of design simpler, eg high-order functional reuse, etc).
that is well named
WTF does that have to do with "duct tape" coding? That's just good coding practice in general, whether or not you're over- or under-designing.
strongly typed
So now we can't even use Perl or Python? The duct tape of the programming world? Jebus...
designed by contract
Once again, that's just a good idea in general.
Frankly, looking at your list, they're either just good ideas, or baseless prejudices, nothing more.
I guess in my experience, your example doesn't really go anywhere to disprove the article. IE I had a project where we followed all the correct design principles and did 2 years of work * 5 developers for a project that was to be the future of the company. Another division had started before us a similar project with slightly different goals. The sold management on their duct tape software that met some of the spec before ours. So my project got canceled. Their duct tape software had to be completely re-written to add the remaining features (8 years later they still haven't surpassed what we had almost done.) The fact that they were done (with something) first won out. The fact that duct tape allowed them to provide the solution, and buy them the time to re-write it, in my mind showed how it makes them more successful (I did replace a bunch of their code with ours, and the correctly written code spawned other projects to use its base, so not a failure.)
So the fact that your co-worker got the jobs, seamed to show people they needed that solution, and thus seams thats the reason you got the time to re-write them. Shows that duct tape programming "works." Even if it isn't always the most efficient method in the long run. IE this is about how many projects have just been abandoned because they were stuck in doing it the right way, where you slap something together, you got your foot in the door, and may buy the time to do it the right way.
First off, Jamie Zawinski no longer programs much. He runs a nightclub.
Second, Joel Spolsky isn't exactly a big name on programming. He's better known as a blogger than a developer. He runs a little company that makes a desktop project tracking tool. That's not rocket science. We're not hearing this "duct tape" stuff from people like Dave Cutler, who designed VMS and Windows NT. Or lead developers on MySQL. Or big names in game development.
Spolsky is taking potshots at the template framework crowd. He has a point there. I've been very critical in that area myself; I think the C++ standards committee is lost in template la-la land. The real problem with C++ is that the underlying language has a few painful flaws for historical reasons, and attempts to paper those flaws over with templates never quite work. (Read up on the history of auto_ptr to understand the pain.) But that's almost a historical issue now. Newer languages such as Java and Python aren't as dependent on templates as is C++. If you get the basic language design right, you don't need templates as much.
... than a half assed product full of bugs in your enterprise: One nobody uses that's been sitting on someone's test server for 2 years.
It's been my experience that if your project takes more than 3 months, someone else's project to do the same job, half assed or not, is the one that will be used. There's always some busybody doing a secret project, which they will show to a VP, usually on their smart phone, while they are buying them drinks at happy hour.
Then when it doesn't scale, they'll find a way to blame their co-workers, who will need to work overtime to make the steaming pile of dung work, while the guy that built it is gathering requirements for his next shitty project. He's a mover and shaker after all!
Git'er done or get plutoed. People don't care if there are bugs, as long as you fix them. They get really pissed when they have to wait ; )
Don't kid yourself. It's the size of the regexp AND how you use it that counts.
I manage a small team of programmers. When I first started, I 'inherited' a developer, let's call him Crufty Joe, who had worked at the company for 20 years and had developed financial and hr routines on the old mainframe and spiffy new oracle apps system. Joe had developed a lot of code, but he was always having to perform updates and corrections...
Before throwing "Crufty Joe" under the bus, you should realize that his "cruft" came from an infinite stream of seemingly-minor change requests that were not part of the original design and had to be "duct-taped" on to the original application.
And I'd be willing to bet that if you stay there for 20 years that your code will look just like his.
"We want to handle this type of customer just like these guys, except when this happens do that." "Except if they're part of this group. Or their name is 'xxxx', in which case do this other thing."
This is why there is, in agile methodologies (or at least the descriptions I've seen of them, there's a whole lot that passes under that name) the usual recommendation is write a unit test, write the code to make it pass, rinse, repeat. /b
I agree with you. I've seen it work beautifully.
It just works less good in chaotic situations. It may not be feasible in a time frame to write unit tests for legacy code as things get tangled (think entanglement with production database entanglements and tight schedules)
My compromise methodology now is to add a unit test whenever a bug is found, for detecting that bug. That way, I don't wast time with testing things almost as trivial as x = 1; x++;..check if x is now 2. That way, I'm confident that the bugs unearthed by usage will not remain. Evidence that this works? Our team's bug count was 2 minor last I checked. The average for other teams (with admittedly larger code bases) is in the dozens.
His company originally coded their software in VBScript. Ok, fine, it was "back then." But over time, rather than refactor on a modern platform (and despite praising .Net to high heaven), they instead extended VBScript to create their own proprietary programming language. All this to run some bug tracking software BTW.
He scores high on the geek cred and he's a good writer, but I don't understand how he is taken seriously as a major authority on software development. There must hundreds of companies out there producing products on the level of things like Fog Bugz or Copilot. They just don't have a founder who obsessively blogs about everything.
Build a man a fire, he's warm for one night. Set him on fire, and he's warm for the rest of his life.
I brought this question up informally to my coworkers. Punishment or shaming, which I'd read about, doesn't seem to have the desired effect. More of them were of the opinion and experience that code reviews went a long ways towards improving programming skills, including one recent Google hire who had good things to say about Mondrian.
Years ago I was an editor of a magazine about Eiffel programming language I wrote this editorial on differences between low-level and high-level of coding.
...richie - It is a good day to code.
We have a whole department full of duct tape developers, writing Business Objects reports and other BI-type code. They can't write efficient database queries to save their asses. As one of the production support DBA's, I get the pleasure of debugging/tuning their crap after it hits production and won't run. Just yesterday, after one of the production Oracle machines fell over, we discovered a query that was piping a whopping 2.4 PETABYTES of data through a SELECT DISTINCT clause. Considering the database itself is less than 300GB, we found this rather interesting. When challenged, the developer responsible for the query says "It should only return about 10 rows". True, if it ever finishes applying the DISTINCT.
Ship first, tune later, I love that philosophy...
No, this is simply not like this. If a static type system compiler fails to compile the file because of a type error, then there is truly a type error in the program. The idea that some such programs would not have caused problems at runtime is dubious, because what programs can actually run cannot be divorced from which programs compile.
The arguments in "favor" of dynamic typing are simply misaimed. More and better static analysis of code before allowing it to execute is a virtue; the lack of static analysis and rejection of code is not an argument for dynamic type systems, it's an argument against it.
The sort of argument that can be made fairly against static type systems is the following:
So basically, static type analysis is (a) desirable, (b) hard to get right, (c) easy to misuse.
Are you adequate?
Except that it isn't. Sure, it starts, runs for a few seconds, and then exits due to typing error.
Most of the time when I have an error, it's not a typing one. Sometimes it's something else the compiler would catch -- misspelled identifier, function or method name I misremembered (or forgot to implement), whatever -- but more often than not, I don't spend a lot of time hitting my face with my palm over a typing error.
No, most of the time, I find that it's my logic: I only *think* I've given the computer instructions that will accomplish what I want it to do. But I've overlooked something, left out a step, forgotten a corner case, whatever.
Having a compiler make sure my types are right doesn't generally contribute much to solving this kind of problem, at least for the common meaning of typing we're usually invoking when we're discussing this issue (e.g., typing as it's supported by languages like Java). You could argue that unit testing is kindof like a big type test (do these modules exhibit certain specified behaviors for their "type"?), and maybe there's a language that treats typing like that, which would be intriguing. But having a compiler tell me something like "class x doesn't have method y"? Not generally germane to most of the issues I have while developing, really, and even when it is, I don't really care if I discover this at run time, particularly since feedback is at least as immediate as what you'd get from a compiler if not more.
And meanwhile, as others have pointed out, I'm spending less time writing convertors/adaptors.
There are problem domains where I probably wouldn't use an interpreted/duck-typed language, but I find I'm more productive when I can use them.
Tweet, tweet.