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."
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.
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.
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.
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.
Why is it that whenever I read an article by Joel I feel like I'm being talked down to?
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 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.
wow, i could write your 4000 lines of code in 3 days.... why does it take you a month?
Because there is a lot more to developing an app than writing code.
I should have been a Geologist.
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.
Always write code as if the guy who has to maintain it is a sociopath who knows where you live.
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.
Your employer measures the utility of a program by how many lines are in it. That's all that's needed to know that your management are clueless and are proud of pushing crap out the door.
God invented whiskey so the Irish would not rule the world.
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
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 can write 4000 lines of code in 3 days too... Or alternatively, I can write 60 useful lines in the 3 days, and be 60 useful lines of code ahead of you.
forgive them if they never write a unit test, or if they xor the next and prev pointers of their linked list into a single DWORD to save 32 bits, because they are pretty enough, and smart enough, to pull it off.
No, I don't forgive them for writing obfuscated spaghetti code and leaving it for me to maintain. Also FTA:
Duct tape programmers tend to avoid C++, templates, multiple inheritance, multithreading, COM, CORBA, and a host of other technologies that are all totally reasonable, when you think long and hard about them, but are, honestly, just a little bit too hard for the human brain.
I laughed out loud when I read this. I write in C++. It's my favorite language. But I can't stand these Duct Tape Programmers who are the ones casting to void * because they can't be bothered with templates. Now I know nothing of COM or CORBA, but multithreading is generally not something you have a choice about. Avoid it if you can, think very carefully about when you need to use it because of the application requirements.
I've seen a lot of things, but I've never been a witness.
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.
That may be true... although personally, I find that when I'm really cursing some other programmer's name and wishing disease and misfortune upon him and his family, it's the work of a "ten-levels-of-inheritance deep wrappers around wrappers that wrap wrappers that generate code on the fly" overengineerer, rather than a spaghetti coder. At least with spaghetti coding, I can walk through it mentally and figure out what's going on (although it may take a while) - with "clever" code, I can't make heads or tails of it without a debugger.
Proud neuron in the Slashdot hivemind since 2002.
Until you run into a 150 KB ten-line behemoth of a file that mixes three different languages complete with conditionals in one language containing blocks of another language with their own conditionals that contain blocks of the first language. You know you deal with a pathologically planning-averse coder when you need to draw a map on a sheet of paper just to figure out how many conditionals deep you currently are.
Extra bonus when they somehow manage to implement an O(n^2) problem in O(n^4).
USE HOT GRITS WITH STATUE OF NATALIE PORTMAN (NAKED AND PETRIFIED)
And also a big difficulty doing big projects with Python - it becomes too damn unwieldy.
Nevertheless, noodle monster bless Python. Right tool for the right job, etc.
Fuck systemd. Fuck Redhat. Fuck Soylent, too. Wait, scratch the last one.
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.
I bet Joel doesn't drive to work in a duct-taped go-cart .... and I bet he wouldn't drive over bridges or work in a building which wasn't designed by a proper, qualified engineers/architects.
Out in the real world his "duct tape" programmer would be called a "cowboy builder".
As for his ranting on C++: He's demonstrated his C++ ignorance enough times for C++ programmers to just ignore his opinion - he still thinks it's just C with added bloat. I agree that multithreading is harder than it looks but templates and multiple inheritance...? Puh-lease.
The final nail in the coffin of the rant is in the last line where he says it's ok to avoid unit testing but that xoring two pointers together is somehow cool. If you weren't ignoring him before you should be by now.
Summing up: Joel has jumped the shark, every article just confirms it more
No sig today...
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."
Bad programmers can write "unwieldy" code in any language. High-level, dynamic, duck-typed languages are not unique in this respect.
The difference is, the app is up and running, ready to ship with the duck-typed languages, whereas people using lower level static languages are still writing converters and reconverters which don't add anything to the actual functionality of the app.
A slashdotter who didn't build his own computer is like a Jedi who didn't build his own lightsaber.
No, I don't forgive them for writing obfuscated spaghetti code and leaving it for me to maintain.
"Spaghetti code" is just a term used by programmers to describe someone else's work.
Except that it isn't. Sure, it starts, runs for a few seconds, and then exits due to typing error.
All duct typing does is move type errors from compile time to runtime, which also means that you can never be sure if you've actually squashed them all. I truly hate that aspect of Python.
Forget magic. Any technology distinguishable from divine power is insufficiently advanced.
For the uninitiated, this is one of the reasons Ruby and Python programmers can deliver broken code in a tiny fraction of the time it takes Java or C# programmers.
Fixed that for you. Static typing is a safety check. Get rid of it, you also get a higher chance of runtime bugs that slip through undetected, and lie dormant until you trigger the exact condition that leads to the bug.
"But", you hear the adherents of dynamic languages saying, "this is what unit tests are for! Just make sure you have 100% coverage, and you'll be fine!". But that's the point - to truly get to that 100%, especially in a reusable framework, it means you have to test things such as someone passing an object of a wrong type to your method - something that is simply impossible in, say, Java. So Java developers may lose on the amount of code because of all the extra type annotations, but win on not having to test type safety violations that the language checks for them.
Of course, in an article about "duct tape programming", this point is probably moot - "duct tape", as described in TFA, strongly implies "no unit tests".
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...
This is getting late in the posting, so I don't expect many people to read this but ...
20 years of developing software has taught me that good enough is good enough. What is good enough for one project, is overkill for another, and nowhere near good enough for yet another. As a software developer, I see my job as turning code into $$$. Good enough means that you have to perform a mental cost-benefit analysis on what you develop.
But what is good enough? That is the variable. Sure, there are twits out there who try to argue that there is exactly one level of "good enough" for ALL projects. Clearly for the products that you cite, 50% is not good enough. But for some things, if something works only half the time, it could (does not translate to will) still be useful enough to be put to use.
Over time, user demands, and competition will push the "good enough" bar higher.
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?
the static languages also "catch" a great deal of non-errors which the programmer is forced to deal with even though they never would have caused problems at run-time
The solution is templates and type inference, not moving type errors to runtime.
Those who would give up liberty to obtain working drivers, deserve neither liberty nor working drivers.
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.