
The Duct Tape Programmer - luu
http://www.joelonsoftware.com/items/2009/09/23.html
======
Untit1ed
The problem with this blog post is that it's long been used to justify writing
crappy code, when it's actually about writing simple code, and those aren't
necessarily the same thing. If your duct-tape go kart falls apart going around
a corner and gives you a permanent injury you're gonna wish you spent a bit
more time at the starting line wondering what to build it out of.

~~~
sgift
> you're gonna wish you spent a bit more time at the starting line wondering
> what to build it out of.

Sure, but usually spending a bit more time at the starting line (or rather
"much more time" or "all the time in the world, until there's no time left and
you still have to use the duct tape version, now in an even bigger hurry")
won't help you find the problem spots. Hindsight bias is very well and alive
and usually all the "yeah, we should have thought about that before" remarks
are just that. You wouldn't have thought about it before, because you need the
scars to tell you "Bad idea, don't do it again."

~~~
waps
As a general rule, decision made due to regret ... well tend to lead to more
regret. That happens to me a lot. What a lot of people don't do after a
project is to first evaluate how well the whole thing worked.

How many bug incidents were there ?

How many times did a design decision have to be refactored out ?

How many times did you really have a problem ?

Then, first things first, take out all problems that were obviously not
project related. The team moved ? Someone went on holiday ? All of those don't
matter.

After that, you'll have problems left. If it's 3 problems, none of which
delayed more than 2 weeks/10%, your project went as well as you can reasonably
expect. Don't change a thing. If after that you arrive at the conclusion that
the project went ~80% as planned, then you've simply done it right. There are
no lessons to be drawn from mistakes, because the fixes are likely to screw
you up more than the "mistakes".

Even when this is not the case, you should limit fixes. Take the top-3
problems, at the very most, and implement a fix for one of them. Then try to
mitigate the second and stay away from everything else.

If you don't you'll have seriously more regrets about your next project a
whole than your current project.

Lots of people generally don't do this. They do a project, then switch
programming languages. That's a decision you should make once in 5 years
(unless you're switching back after a disappointment). People seriously
overcompensate. From management to developers. Redesigning an entire
organisation because one bad apple leaked something is very likely not
justified, and similarly a rewrite is almost never justified.

------
joesmo
'Zawinski didn’t do many unit tests. They “sound great in principle. Given a
leisurely development pace, that’s certainly the way to go. But when you’re
looking at, ‘We’ve got to go from zero to done in six weeks,’ well, I can’t do
that unless I cut something out. And what I’m going to cut out is the stuff
that’s not absolutely critical. And unit tests are not critical. If there’s no
unit test the customer isn’t going to complain about that.”'

I couldn't agree more. That's what I cut out as well when up against a
deadline. The problem is, when is one not up against a deadline in the
professional world?

Because of a combination of no planning, bad communication, and just plain
laziness on the part of product, I got a chance to see what not being up
against a deadline in the professional world is like. For a few months, my
team wrote beautiful code, did in-depth code reviews, tested everything that
could be tested, and dotted all the i's and crossed all the t's. To be honest,
the pace fell even more than I expected as other team members who didn't know
when to leave well enough alone just kept on making or suggesting unnecessary
tweaks and re-factorings. While it was slightly cleaner and better, the code
we wrote then was only marginally so compared to the code written in haste at
crunch time. If I had to put a number on it, it'd be ten percent better. For
two or three times the amount of time and effort put into it. The point is
that there is always a balance that needs to be found.

I have seen and worked with the type of code that Joel refers to and it's
definitely just as bad as any spaghetti. I have also worked with people who
intentionally over-engineer or spend a lot of time on unnecessary minutiae
that overly complicates code and the design. These are real problems indeed
and they lead to code that looks nice from a bird's eye view and even a short
inspection but leads to screaming when you have to work on it. I think both
the duct tape engineer and his opposite are both extremes to be avoided most
of the time.

~~~
hckr1292
"I think both the duct tape engineer and his opposite are both extremes to be
avoided most of the time." Very true! Everything in moderation.

My first job in software development was addng features or fixing bugs in
Drupal sites built by people who had left the company. These were fantastic
engineers, but I pulled my hair out every day and fantasized about unit tests,
documentation, or even a clue about what was going to happen next.

Even with unit tests today, I still make mistakes -- sometimes big ones. But I
also recognize that for software edifices to survive, you have leave a solid
foundation for others (or your future self) to build on. Too much engineering
and there's company left to employ you. Too little and the product might ship
but it doesn't work.

~~~
mchahn
> Everything in moderation

Including moderation.

------
skatenerd
Multiple inheritance often makes it extremely difficult to tell where my code
is coming from.

When you don't use inheritance, you often get to refer to another module _by
name_. E.g.

`my_dependency.fetch_data(123523)`

With multiple inheritance, however, that other module has become your own
"self"!

Suddenly you're stuck with:

`self.fetch_data(123523)`.

And if you want to find the source of `fetch_data()`, you basically have to
grep / look through all seven of your base classes.

If you're lucky, the definition you were looking for calls `self.flush()`,
where `flush` isn't defined on this class. It's actually intended to be
defined on _another_ base class, which is imported by the multiple-inherited
subclass.

So, you effectively have a "DSL" whose "statements" consist of your choice of
base classes. It's impossible to determine what's a legal "program" in this
"DSL" until you run the thing and get method-missing errors.

~~~
fit2rule
>Multiple inheritance often makes it extremely difficult to tell where my code
is coming from.

Thus the rise of the "can't do anything without an IDE" developer ..

~~~
collyw
What exactly is the problem with IDE's?

Why should I have to learn a hundred cryptic keyboard shortcuts to get what I
consider normal functionality? I have in the past used Perl's command line
debugger. Why would I want to do that when I have a far more efficient
graphical debugger in Eclipse?

I work with bioninformaticians, and many of them are too lazy to have ever set
up an IDE. Most of them won't have had autocomplete until Kate included it.
Barely any of them uses a step through debugger. Its like a revelation when
they ask me for help and I show them it on my machine.

~~~
fit2rule
_What exactly is the problem with IDE 's?_

    
    
      You appear to be advocating a new:
    
      [ ] cloud-hosted [ ] locally installable [ ] web-based [ ] browser-based [ ] language-agnostic
      [ ] language-specific IDE. Your IDE will not succeed. Here is why it will not succeed.
    
      You appear to believe that:
      [ ] Syntax highlighting is what makes programming difficult
      [ ] Garbage collection is free
      [ ] Computers have infinite memory
      [ ] Nobody really needs:
        [ ] a REPL  [ ] debugger support  [ ] a local filesystem
        [ ] to interact with code not written in your IDE's preferred language
      [ ] The entire world speaks 7-bit ASCII
        [ ] Scaling up to large software projects will be easy
      [ ] Convincing programmers to adopt a new IDE will be easy
      [ ] Convincing programmers to adopt a language-specific IDE will be easy
      [ ] Programmers love learning new keybindings
      [ ] There is only one operating system and it is
        [ ] OS X  [ ] Windows  [ ] Linux  [ ] iOS  [ ] Android  [ ] the DOM
    
      Unfortunately, your IDE (has/lacks):
      [ ] vi keybindings
      [ ] emacs keybindings
      [ ] Syntax highlighting
      [ ] User-configurable indentation
      [ ] Macros
       [ ] Written in JavaScript [ ] Written not in JavaScript
       [ ] Written in a scripting language you made up
           [ ] which is a Lisp
             [ ] A windowing system
      [ ] Version control
       [ ] Only using git [ ] only using github.com [ ] not using git
       [ ] using an RCS of your own devising
         [ ] Its own platform-independent look-and-feel
       [ ] that was designed by a programmer
       [ ] based on yesterday's design fads
       [ ] applied inconsistently
         [ ] A look and feel specific to one operating system
       [ ] that was last widely used in 1989
       [ ] and was known to cause seizures
    
      The following philosophical objections apply:
      [ ] Programmers should not need to understand CSS to change their font
      [ ] The most significant program written using your IDE is itself
      [ ] The most significant program written using your IDE isn't even itself
      [ ] Graphical programming presumes programmers can draw pictures better
        than they can type words
          [ ] The implementation is closed-source
        [ ] covered by patents  [ ] not owned by you
          [ ] The DOM is not an application framework
      [ ] The name of your IDE makes it impossible to find on Google
      [ ] Your IDE assumes JavaScript can be made infinitely fast
      [ ] You seem to think static analysis is worthless
    
      Your implementation has the following flaws:
      [ ] JavaScript is not faster than C, C++, or Java
      [ ] The DOM is not a windowing framework
      [ ] It crashes on any file larger than 32k
      [ ] You provide no way for users to run the program they are editing
      [ ] You require the user to check in code before it can be run
      [ ] The IDE crashes if you look at it funny
      [ ] You don't seem to understand basic optimization techniques
      [ ] You think a single string is an acceptable data type for a text editor
    
      Additionally, your marketing has the following problems:
      [ ] Unsupported claims of increased productivity
      [ ] Unsupported claims of greater "ease of use"
      [ ] Obviously faked screenshots
      [ ] No one really believes that your IDE is faster than:
        [ ] vi  [ ] emacs  [ ] Eclipse  [ ] Visual Studio  [ ] IntelliJ [ ] Notepad
          [ ] Rejection of orthodox user interface design without justification
      [ ] Rejection of usability principles without justification
      [ ] Rejection of established platform conventions without justification
      [ ] Rejection of basic user interaction without justification
    
      Taking the wider ecosystem into account, I would like to note that:
      [ ] Your example workflow would be one key command in: _______________________
      [ ] We already have an IDE in the browser
      [ ] We already have an IDE that can be scripted using
       [ ] Python [ ] JavaScript [ ] A Lisp [ ] Lua
         [ ] You have reinvented vi but worse
      [ ] You have reinvented emacs but worse
      [ ] You have reinvented TextMate but worse
      [ ] You have reinvented Eclipse but worse
      [ ] You have reinvented Notepad but worse
      [ ] You have reinvented Notebad better, but that's still no justification
      [ ] You have reinvented ed but non-ironically
    
      In conclusion, this is what I think of you:
      [ ] You have some interesting ideas, but this won't fly.
      [ ] This is a bad IDE, and you should feel bad for creating it.
      [ ] Programming in this IDE is an adequate punishment for inventing it.

~~~
collyw
> You appear to be advocating a new:

I am not advocating new anything.

I personally use Eclipse / Aptana. I said that in my post and asked what the
problem was with it, and gave some of my reasons for using it.

------
sanderjd
The title could use a "(2009)" \- I thought this was a new joelonsoftware
article.

~~~
hckr1292
ditto! I was disappointed not to have fresh meat myself.

------
dlu
At a startup, often duct taping is exactly what you need. It can't be
worthless code, but good enough is often what's needed.

You need to build something that will get shipped and work for the next little
bit. Then, when you have an avalanche of customers you get to replace the
engine in mid-flight. That's the dream.

The scenario where you build hugely scalable infrastructure with squeaky clean
code is not the dream.

------
mastermojo
10+ years and billion+ dollar valuations, Facebook changes it's motto from
"Move fast, break things" to "Move fast, stable infra".

I guess thats basically the time and point for you to start worrying about
duct tape.

------
forrestthewoods
Right now I'm working on save/load for a game that is overflowing with duct
tape code. Yes it shipped and did well. But now I'm paying for all the sins of
all the duct tape used by all the coders. I'm not sure I'd change anything in
the past but I do reserve the right to bitch about things written that aren't
fully correct but close enough... until save/load is considered and then it
just doesn't work at all. Grumble grumble grumble...

~~~
fit2rule
Every time you bitch, consider this: you've still got users.

It'd be appropriate to bitch about it if you didn't have users. But, in the
end, it doesn't matter how fancy things are: the user is the only thing that
matters. Ever.

~~~
tragic
Until the users want a new feature - save/load, say - and you can't add it
without breaking the toaster in the office kitchen. And so the users bugger
off to play Candy Crush Massacre or whatever :-)

~~~
fit2rule
So this is why you release early and often, and work hard to fix the problems
before your users get to them.

~~~
peri
That's great for some products. Others require a big initial rollout to
justify the capital expenditures involved with development.

------
mattcaldwell
I'm feeling all these mixed emotions right now.

------
jiraaya
I have started taking "I write bad code", "I don't write unit tests" etc with
a pinch of salt. I think in any real world scenario there will be factors that
pull the code in one direction or the other. Sometimes the most important
thing is to ship, sometimes the most important thing is to ensure that you can
keep shipping. It is entirely contextual.

~~~
collyw
Exactly.

I build and manage an in house database. The data model changes frequently. I
have started adding in unit tests in the past, but they are rarely worth the
time (in these circumstances). I estimate that creating unit level tests and
fixtures would probably treble the time needed for features, and would catch
maybe 10% of the bugs that appear.

Uses request a feature. I build it. I show them, ask them to test it and tell
me if they have a problem. I get plenty of testing done. Just not in the unit
test way.

Now I imagine if I had an online app used by millions of people and I was
doing a big upgrade I would have a different attitude towards the way I test.

------
xupybd
I like this article. I was good at the crazy multi threaded stuff at uni. Now
I find I have a lot to learn about making real life products. 3 Years in and I
have to admit attention to detail and simple yet robust solutions are more
important than understanding the latest and greatest way of doing things.

------
habosa
Sometimes duct tape is the way to go, especially when you are working on a
project with a small-ish team where your 'hacks' can be easily understood by
everyone.

This article is very relevant to my life recently. Recently I have been
working on a tool to boot a full development environment in VM. It's just a
series of shell scripts (managed by Vagrant, so some "shiny", but nothing
crazy). Everyone wanted me to use docker and someOtherShinyThing.js etc, but
in the end the shell scripts are simple, predictable, and they work really
well.

~~~
tsotha
I'm on the other end of it with my current project. The "architect" managed to
wire about a dozen third party libraries and frameworks together to create a
Frankenstein monster that's quite literally unmaintainable. Every day is a new
day of Jenga - touch anything and it all just collapses.

The funny thing is it didn't save time at any point in the project. the
learning curve to configure all that was so steep we could have written it
ourselves in less time. And sure, with a few dozen scattered lines of code I
can add a new feature that's almost exactly what the users are requesting.
After three days of perusing stackoverflow for a few days and spending another
three days trying to figure out where the new cryptic error message is coming
from. "Socket timeout"??? Which socket? For what?

~~~
dilap
I feel for ya. People often rail against reinventing the wheel, but 36 times
out of 37, I'd rather have an in-house created wheel that rolls how we know it
should with code we understand than some 3rd party bag of voodoo that
supposedly roles in the desired ways, maybe.

~~~
collyw
I would far rather have something put together with well known, documented,
tested third party libraries than some undocumented in house crap that one
"superstar" developer knows how to work and no one else.

~~~
tsotha
You _think_ that, but in my experience the "well know, documented, tested
third party libraries" try to be all things to all people. So when you just
need something to cut your steak with what you get is a Swiss army knife with
twenty different blades of which you can identify three without spending a
week poring through documentation.

Instead of just looking at fifty lines of code to see what the "undocumented
in house crap" is doing, you'll be spending all your time on stackoverflow
trying to figure out why these third party libraries don't play well together.
"Has anyone had this problem with version 3.3.2 of JLSHE and version 8.7 of
Loopdidoodle?" Oh, I think I need 3.3.4. But the developer of my GUI framework
says only 3.3.2 is tested and I'm on my own if there are problems. Somebody
has a workaround but it only runs on RedHat when I'm running Debian. Should
work okay if I recompile it, though... except the kernel version I'm running
is too far behind.

And your assumption third party libraries are any better quality than a
focused in-house solution is a bit naive.

Finally, a few years down the road the mind share for half your third party
libraries and frameworks will have dwindled as the people you were counting on
to maintain them found something shinier.

~~~
collyw
Documented and well known is preferable to most of the in house stuff I have
come across. Need a Django developer, then there will be a few out there. A
new developer on your own in house framework is _always_ going to need some
time to get up to speed.

Sure I may be on Stack Overflow for some answers, but you can guarantee that
the in house equivalent won't have any Stack Overflow answers at all.

My personal experience is that open sourced libraries in CPAN / PyPI are
almost always of a higher quality than in house stuff.

Maybe it depends on the language. When I go for Python / Perl libraries, I
usually get something of a high quality. JavaScript stuff always seems a bit
more like you describe.

I would say that the developer of the in house stuff leaving is going to be at
least as much of a problem as people abandoning open source projects (which
are open source, so you can continue to maintain them yourself).

------
bsdpython
Keep it simple stupid and focus on the end product - that's all you really
need to know

------
peri
This is a great article, but the comments make me feel like I'm twice as old
as I actually am.

I think that maybe if we called these programmers "gaffer tape programmers",
some of the sense might be clearer to programmers who've come to the field
(like me) from a linguistics and theatre background, not a traditional
mathematical one.

------
spain
As a programmer who is too often focused on perfection, yes.

------
DownvoteMeToWin
Currently rewriting every single line of UI code a pile of duct tape
programmer spewed out over the span of two years. Writing functional tests so
I know when I break the UI. Documenting everything. Hitting all deadlines.

Using multiple inheritance. Lots of It. In fact, no file is over 150 lines
long. Composition pattern in full effect as well. I hope it wards off duct
tape programmers for life.

> 2015

> multiple inheritance is hard

ducttape pls

~~~
skatenerd
Composition...isn't the same as inheritance?

~~~
DownvoteMeToWin
Why not do both?

[http://programmers.stackexchange.com/questions/134097/why-
sh...](http://programmers.stackexchange.com/questions/134097/why-should-i-
prefer-composition-over-inheritance)

~~~
skatenerd
I didn't see that he wrote "as well". lol.

