Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise.
If this question can be reworded to fit the rules in the help center, please edit the question.

@Steve: I read that before I posted. It's related but asking that question would not answer the question I have asked here. Hence, I have explicitly asked the question.
–
CarnotaurusApr 16 '11 at 11:58

The immediate cost of fixing a bug properly + the immediate cost of not having it fixed in time

vs.

The immediate cost of a dirty fix + the ongoing long term cost of the dirty fix

If fixing it properly, means that you miss a deadline that would have got you a staged payment, or means that a competitor gets to market before you, then that cost could be quite high and it may have been worth incurring the technical debt instead. But remember that the longer you leave that debt unpaid, the more interest you are going to accrue in terms of the cost of supporting the code and adding new features.

Beware though, if you use being pragmatic as an excuse for laziness and keep on racking up the technical debt, but never pay off earlier debt through re-factoring, you may find that the debt rises so high that bankruptcy is the only remaining pragmatic option. *8')

It's true that a dirty "fix" is not a fix (a). If a product has a problem, a clean fix is intended to fix this problem to be able to:

Reuse the concerned part of the product and be sure that there are no known issues with it,

Don't have to return to modify code again later to solve bugs.

With a dirty fix, the developer:

Can't reuse the concerned part, because she cannot be sure that it will work as expected,

Must return later to rewrite the code correctly.

So instead of spending more time fixing something, a dirty fix is used to spend less time immediately, but more time lately by forcing to return and make a clean fix and by forbidding to reuse code meanwhile.

Of course, this may not apply to every dirty fix, and it also depends on what we call a dirty fix or not. Example:

A user submits a report saying that a program gives an incorrect result when the input is equal to 39.5. A stupidly dirty DailyWTF candidate fix would be to do:

Chances are that in a few days or weeks, another report from another customer will tell us that the output is also incorrect for some other input value.

A less dirty fix would be to check the algorithm, see where is it broken, and fix it, without fixing the unit tests. The chances to see it break again are smaller, but it can happen, and there is a need to return later to add unit tests, maybe add comments, enforce style guidelines, write documentation, etc.

So yes, some fixes dirtier than others (b, c). If some are more acceptable than others is up to your company guidelines.

Dirty fixes show a pragmatic use of ones time (d, e). At a precise moment. Because by spending a few minutes less, you waste hours of your own time lately (or your colleagues will spend later hours cleaning your fix). That's why dirty fixes should be discouraged especially in a team. If a developer makes lots of dirty fixes, then leaves the company, the other people of the team will have hard time cleaning the fixes.

How do we stop attitudes like "dirty fixes show a pragmatic use of ones time and should not be discouraged" from becoming standard practice?

By enforcing best practices, but also by ensuring that the developers in a team/in a company communicate well about what they're doing. Too much pressure and stress from management can also force the developers to use more dirty fixes just to finish quickly. This is especially true when the team manager is inexperienced enough and/or don't care about code quality.

There are times when it's worth five minutes before the fix and three hours later to do it right, as opposed to two hours to do the fix right in the first place. This usually means things were badly managed to begin with, but it can happen. I have seen it only rarely.
–
David ThornleyApr 18 '11 at 13:39

if(input == 39.5). That in itself is a WTF.
–
Artefact2Apr 18 '11 at 20:01

I've certainly put in some horrible fixes in my time, but the code I was working on was beyond redemption - a complete mess of PHP that was copy/paste mass of dependencies everywhere (with variations) and the most random database "design" I've ever seen. Of course I'll never willingly show that code in support of a job application!

Normally I go with a) At the very least what I do should be understandable and maintainable. If I can improve/refactor a little at the same time, so much the better.

d) and e) are simply lazy... you may save 30 minutes now, but what of when the next update / fix is needed in six months? It's false economy.

In general hacks/dirty fixes should be avoided and rejected. There are exceptions though.

If the framework/language is too limited to do it properly without massive project restructure.

If the framework/language has a bug that must be worked around

If there is no foreseeable way to actually cleanly fix the core problem(related to #1)

For #3:
For instance, I've done some very odd things working around ASP.Net's crooked page lifecycle. I understood exactly how every event was called and why my code wasn't working. So I ended up calling _Click methods manually by checking the Form array myself earlier in the page lifecycle than events are normally called.

For #1:
I had a SQL query being built manually so it ended up being like

So it ended up that if none of the options were selected, I'd get a syntax error. My other option was to constantly build a if(Option1 | Option2 | Option3) which I thought to be a maintenance nightmare for when options were added. So I fixed it with a single change:

query="select * from table where 1=1";

I'd consider this dirty/a hack because it's not immediately apparent why 1=1 was put there. I of course commented the hell out of it explaining it. But it's still a hack. The alternative "proper" way was harder to maintain however.

I think the question of whether a "dirty" fix should be unacceptable or discouraged presumes that there is a clear distinction between a "dirty" fix and a "clean" fix, and I don't think there is. I have applied fixes I thought were "clean" that ultimately proved to be "dirty" compared to the next fix. (Less often, I have applied fixes I thought were "dirty" that ultimately proved quite "clean"). I think it would be more valuable to distinguish between a "dirty" fix and a "dirtier" fix, with the former being preferable, all else equal.

Both the "dirty" and the "dirtier" fix should resolve the immediate issue, but when compared to the "dirtier" fix, the "dirty" fix should reduce the likelihood of future error and, should an error occur, reduce the effort required to resolve that error. That might require as much as refactoring the code, or it might require as little as documenting the code and logging its execution, so that the next developer might be better able to diagnose and fix the error.

As for how to discourage developers from choosing the "dirtier" fix, I'd say, stop encouraging developers to chose the "dirtier" fix by explicitly preferring the faster fix and thus implicitly preferring the "dirtier" one.

In general, a "fix" or a "hack" is a bad thing. And in school we learn how to not do fixes. But in real life, when time is of the essence, fixes happen like constant Id's in code, not making the code general enough e t c. As long as everyone from the project agrees of what is beeing done, I think it's OK. The risk is that the code will not be changed later on to be corrected. The risk is that one is building a labyrinth of code which will be harder and harder to correct the longer the fixes stay. Also time to change fixes increases logarithmic the longer they are allowed to stay in the solution.

So I agree on c) and d) if possible - meaning if you need to do a fix, comment it well and make the code simple enough for the next programmer, who might be the one to correct the fix. Then you have made the most of the current situation.

If the next version of the code is being actively developed, a dirty (quick) fix may be an appropriate action on the production branch. The fix should be as clean as possible, and certainly should not qualify as a DailyWTF candidate. It may allow you to fix the production branch in cases where the clean fix will need more work than is practical.

If you do use a dirty fix, it should not be merged into the development branch. With few exceptions (dropped features), all production fixes should be applied to the development stream. If you can apply a clean fix, merging it onto the development stream is appropriate. If not, the fix should be redone cleanly on the development stream.

Question is largely academic.
Most often, in a production environment, there's no time to do things "clean" when a problem appears on a production system.
Thus you take the fastest route to fix the problem, thus limiting downtime as much as possible.
That might be a "dirty fix" in that it's not the best looking of code, but it gets the job done which is far more important as downtime means lost revenue, code that doesn't look nice just means lost brownie points for programmers' egos.

If it's a real hack, you're probably going to tag it for refactoring at the earliest opportunity (i.e. when that part of the code is next scheduled for change, NOT in the next release just because you want to get rid of it), but it will go in now because there's simply no time to do things nicely.

Such is the world of deadlines, working to real world requirements rather than homework assignments.

True points except commonly there is never a time when "that part of the code is next scheduled for a change", or if it is then there is so much to be done that you can't spend the time to fix the hack, and so a refactoring never really happens.
–
Wayne MApr 18 '11 at 20:18

if the hack does its job well enough there's no reason to touch it except to stroke your vanity for wanting to have "perfect code", there's no reason to touch it.
–
jwentingApr 19 '11 at 6:15

I respectfully disagree with that; if the hack did it's job well enough, it wouldn't be a hack but a proper fix.
–
Wayne MApr 19 '11 at 12:08

if it does its job, it can still be a quick hack that wouldn't pass a regular code review process for being "dirty". That doesn't mean it's not a proper fix indeed, which is my point, a dirty hack doesn't have to be bad :)
–
jwentingApr 19 '11 at 12:17

My view is that there is never a good reason for a dirty fix, only excuses that hint at a larger problem. Sometimes that problem is something you can't fix (e.g. no management buy-in, issue with the framework/language you are using) but it's still always an excuse to cover up something else.

Not surprisingly I try to avoid doing things the "dirty" way whenever possible, since my experience is that you never will be able to fix it properly and "pay back" the Technical Debt.