I <3 Steve McConnell*
Coding Horror
programming and human factors
by Jeff Atwood

June 17, 2008

Coding For Violent Psychopaths

Today's rumination is not for the weak of heart. It's from the venerable C2 Wiki page Code For The Maintainer:

Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.

carny

Perhaps a little over the top, but maybe that shock to the system is what we need to get this important point across to our fellow developers.

If scare tactics don't work, hopefully you can develop a grudging respect for the noble art of maintenance programming over time. It may not be glamorous, but it's 99% of the coding work in this world.

[advertisement] Peer code review without meetings, paperwork, or stopwatches? No wonder Code Collaborator won the Jolt Award.

Posted by Jeff Atwood    View blog reactions

 

« Physics Based Games Department of Declaration Redundancy Department »

 

Comments

given the hiring policies in this place, it's not so much a guideline as a rule.

secretGeek on June 18, 2008 04:58 PM

I has very bad memory, and I don't even remember codes I wrote 2 weeks ago. So I always design first, and try to make the structures simple, refactor the codes every half hour, review design every 1 or 2 days through reverse-engineering of UML tools, and supplement more comments. With simple and clear structures, and consistent design patterns for similar stuffs, I leave traces to myself for the future maintenance, because, in 2 week time, I will become a fresh programmer touching codes left by the other (actually me).

Andy Wong on June 18, 2008 05:07 PM

I wish some of the code I am maintaining was written by someone who followed that guideline. Sometimes I feel like becoming a violent psychopath and hunting someone down. Here is an example from today:

// Goto used to enhance simplicity and readability.
label GOTO_NEXT;

That is the original comment used to explain the use of the GOTO. I would think GOTO and Readability are mutually exclusive.

Jim McKeeth on June 18, 2008 05:13 PM

I'm an obsessive commenter in my own code, and almost every few lines of code comes with painfully detailed documentation on what kind of stuff the code does to each variable, so I think the psychopath code maintainer would still come after me: for commenting too much

pikapi on June 18, 2008 05:22 PM

Being a student I've never had the pleasure of dealing with real-world code, but maintaining what some students write in their projects brings me ever closer to slamming my own head through my monitor in despair. There's a fine line between not being able to code well and having better things to do than to code well, and when some people write awful code just so they can leave early to watch TV it really bugs me.

Mike on June 18, 2008 06:04 PM

Oh man, I so want to axe murder some of the people who wrote the god-awful code I have to maintain.

Kooch on June 18, 2008 06:07 PM

Jeff, why couldn't you tell this to the person who wrote the shit I am currently working on?!

Josh Stodola on June 18, 2008 06:07 PM

Heh, I first heard that advice today, but from a completely unrelated source (a guy giving a talk on typing systems for scripting languages at ITA software). I think it's good advice: "Throwaway code" often isn't and good documentation is key (especially in weakly-typed languages).

l33tminion on June 18, 2008 06:19 PM

lol! This is perfect advice for myself as I prepare to hand off a little VBA 'app' I've been working on - I think I've commented to code and even supplied a semi-detailed design doc to go along with it. It's not complex code, just a ton of it, mostly revolving around form validation.

Maybe next week I'll get to take the training wheels off :S

David Vessey on June 18, 2008 07:33 PM

I heard that quote first from the missed Kathy Sierra. I have an even better quote:
"Always code as if the person who ends up maintaining your code is going to be yourself, because at first it will always be"

ilcavero on June 18, 2008 07:42 PM

There's only one thing worse than no comments. And that's comments that are WRONG. I inherited code where the guy started out meaning well, but then when he got in a hurry would copy code, change it, but leave the comments alone.

Benton Jackson on June 18, 2008 07:58 PM

Sorry Jim, just need to vent a bit
What up with everyone hating GOTOs? There's a good reason why they are still here. Sometimes there just isn't a nicer way to show that without taking a horrible lag-hit.
GOTOs are like OO, like functions, like everything in programming a tool that has it's moment and use, rare indeed, but it's still there. And believe me, I've seen spaghetti code built entirely with objects (can you imagine having to jump up and down in object hierarchies to see how a function works? WHY?)
Dijkstra talked about misuse of GOTOs to jump all over that code which made it impossible to read and didn't even help for efficiency that much. Thinking that means GOTO should never be used is like thinking that the word like should never ever be used, not even on similes, because your english teacher said that people shouldn't use like as much as they do.

Charlie Lobo on June 18, 2008 08:08 PM

Most of the code I have to work with is always written partly the old way, partly the new way, partly "I thought we got rid of all that", and partly stuff that doesn't do anything, but looks like it does, and basically a mess. I'm sure it was coded well in the first place, it just got blended together with "better" code.

Andy Chase on June 18, 2008 08:17 PM

A very good habit I was taught in university was to comment first, code later. What approaching a programming task, write out the comments for the code that you haven't written yet. Helps you plan and you end up with detailed comments when you're done.

Daniel Cooper on June 18, 2008 08:53 PM

Oh, boy! Is it just me or is everyone else also scared [insert vulgar slang for feces here] by this picture? If the world had more zombies, we'd all be better coders. Right, Jeff? :-)

Elvis Montero on June 18, 2008 09:04 PM

I just got my first coding job, and it is maintaining and bug fixing. Its hard to get used to. I feel you.

Ian00 on June 18, 2008 09:08 PM

Code is in maintenance from the second it's checked-in, just like software is legacy the minute it's in production.

Legacy on June 18, 2008 09:44 PM

Poor choice in picture my friend. I comment my code generously and coherently... not sure programmers that document well deserved this. :(

Patrick on June 18, 2008 09:52 PM

Hell is other people's code!

david on June 18, 2008 10:37 PM

I choose to write code in such a way that the person who ends up maintaining the code believes that I am a psychopath and likely know where he lives. I achieve this by leaving threatening comments dispersed throughout the lines, as well as short bits of prose that details my abused childhood. This way I can pretend to do my job and after I'm gone he will be too afraid to tell anyone out of fear of me murdering his cat.

Viktor on June 18, 2008 10:49 PM

Regarding what was said by secretGeek I must definitively agree with that. It happens always to me too and I do the same things that he does.

On the other hand I usually only comment the 'dark' operations that are in my code because I try to code in a way that comments are not needed.

Something like

For rowIndex:=0 To dataTable.Row.GetUpperBound(0)
datatable.Rows[rowIndex].Column("money") = currentMoney
Next

Doesn't needs much comments because its selfexplanatory.

SoMoS on June 18, 2008 11:42 PM

Patrick - you know the picture's not real, right?

Mark on June 19, 2008 12:22 AM

oups man the picture is quiet bad !! :)

Omar Abid on June 19, 2008 12:32 AM

I'm not really understanding your post or what it's aiming to!
I think you have to review some of the articles your are publishing here

Tips on June 19, 2008 12:35 AM

yeah! keep us motivated!

David on June 19, 2008 12:40 AM

Some great advice! Love the image, what is it from?

Ben on June 19, 2008 01:12 AM

I must admit that I've been through the "Who wrote this sh*t??" process, only to find that SCC tells me "You did. But quite a long time ago".

Rather than beating myself up, it gives me the opportunity to see how my coding has changed (and, hopefully improved).

Roddy on June 19, 2008 02:00 AM

I actually found these comments in some c code I had to look at a while ago.

C is not my usual language of choice but knowing it does come in handy every once in a while ;)

The comments were all written by the same developer who was actually quite good but sometimes he had a bad case of sense of humour failure.

/*I don't know what the f*** this is supposed to do*/

And

/* Some months later..........
* I commented the code, and guess what, it didn't help :) */

And sometimes he would get quite frustrated
/* F***, F***, F***, F*** */

and

/* F*** me backwards.......
* This is such a lot of effort just for some lazy ass in <Customer name withheld from post for obvious reasons>. *sigh*
* I REALLY don't get paid enough for this :( */

Ron on June 19, 2008 02:29 AM

I'm not so sure that simply commenting code solves the whole problem, and formal UML diagrams can sometimes be confusing in themselves.

I've introduced the concept of writing a brief technical overview for each feature or module that each person implements; these normally contain UML diagrams but at the same time a description to go along with this helps a lot.

Each project has a wiki where we store these documents.

The problem, as always, is when you have the opportunity cost of Developing a New Feature versus Documenting an Existing Feature.

Duncan on June 19, 2008 04:03 AM

That's in the first chapter of Perl Best Practices by Damien Conway.

I think it might've replaced 'violent psychopath' with 'axe murderer', but the sentiment is the same.

dnm on June 19, 2008 04:53 AM

It takes time to learn to write excellent code, so to me it seems that writing bad code is the forgiveable mistake of inexperienced programmers. But learning to document your code should be the first thing you learn in CSC 100 course.

After major reductions in workforce in our organization, I've inherited the code of several other (much younger) developers. I am willing to put up with spaghetti logic if I have to, but there is no excuse for not commenting or using meaningful identifiers!

I have found several mistakes in their code which they probably would have caught themselves had they taken time to document!

Good thing I don't know where they live. ;-)

Vadim on June 19, 2008 04:55 AM

Merely adding comments rarely helps and they often become lies when code is updated but comments are not. A better methodology would be to refactor the code such that you can read what it is doing and not need comments. By which I mean variable names that are longer and descriptive and breaking functions down into sub functions that do exactly a single thing and renaming it to represent that single thing. (Single Responsibility Principle)

JohnM on June 19, 2008 05:13 AM

I'm on my second programming job now and both places have told me NOT to comment the code. They say it's a brittle association that just ends up making things worse because no one updates the comments when they update the code.

It's certainly true about the failure to update the comments, but what's the correct path? The first job was getting on the unit test bandwagon and the champion of that push claimed that the tests document the code. I didn't get much out of the stuff he had already done though.

Anyway, that's what I've seen so far in my brief career.

KM on June 19, 2008 05:18 AM

this is especially true for me as i maintain my own code, am a raving psychopath and know where i live.

i need to watch out for myself. :P

Jheriko on June 19, 2008 05:48 AM

I must be lucky - I have really bad short-term memory, so even from my earliest days in college I always wrote my code (and comments) so that I could come back and figure out what I was doing - because the chances were that in a few days I'd have forgotten!

I think that should be a required thing in college programming classes - give an assignment, have the students program it, and then archive it until the end of the semester and give it back to the students and have them maintain it (make changes, or something). That'll give them some appreciation for good commenting practices!!

Keithius on June 19, 2008 06:00 AM

ilcavero,

"Always code as if the person who ends up maintaining your code is going to be yourself, because at first it will always be"

That's wrong, and Jeff is right.

People will build for themselves in exactly the way they like things. They'll use technologies or methods that none of the rest of the team use, and they'll be just fine with that.

And everything will be fine until they go on holiday and the system falls over and someone with little experience has to fix their code.

Tim Almond on June 19, 2008 06:22 AM

If you at least learn and can see you own mistakes later on must be a good sign, a sign that the brain still function and that there is a progress ;) One shouldn't expect everyone to write "perfect" code from start. What one think is perfect today can seem pretty bad after a while. But, there are people that do not improve over time, they should be doing something else I think...don't imagine they even read codinghorror.

Edward on June 19, 2008 06:23 AM

But its more cool to see how concise I can make my code, not how readable and maintainable it is! ;)

Rob Breidecker on June 19, 2008 06:29 AM

Hmm... I've use the Pseudocode Programming Process since before I read about it in Code Complete (Good book, Thanks Jeff!). And it generally works really well for me. I leave the Pseudocode in comments to tell future programmers what is going on. This process also helps keep the code and comments in sync because I even write the pseudocode for new features or changes to a function/procedure.

I've never really worked on a big programming team, generally there are no more than 3-7 programmers on the projects I've worked on. And a lot of times it was just me. I am an insecure programmer, so I comment just in case I did something that seemed brillinat to me, but is actually bad, bad, bad. That way if someone that is better comes along while I am still there and they see it, they can say, "Hey, you know you can just do ...." Then I learn and they get their ego fed.

But then again, I also code for readability over putting in the slick "I can write the entire function in 1 line C approach".

My favorite comment I've come across while bug fixing someone else's code -> (* This entire function is commented out in case the b!tch changes her mind... again! *)

Wayne on June 19, 2008 06:47 AM

ASDKLJAASKJ GRRRRRRrrrrrrrrRRRR

YOU KNOW WHO DIS IS? jbarthalomewe?

WHER I FIND?
G
asdkj
qweSDJJJJJJ!!!!!!!!

John on June 19, 2008 06:50 AM

The absolute worst crap I've seen is not just checking in code that's logically wrong but also doesn't even compile! In college if the code didn't compile you got a zero but dang the folks in industry are supposed to be pros! Unbelievable! I try not to think of the craptastic code and all of the total rewrites that need to be done and then I can sleep well at night.

o.s. on June 19, 2008 07:06 AM

You can't understand my code because it's so well written.

Luc M on June 19, 2008 07:07 AM

@KM You don't write documentation and code like they're just a different form of representation of the same knowledge. DRY.

Write documentation for high-level knowledge, not low-level knowledge.

The Pragmatic Programmer book mentions this too: …"The comments will inevitably become out of date, and untrustworthy comments are worse than no comments at all."…

Arthur on June 19, 2008 07:09 AM

Jeff that photo is pretty scary !!

Ahmed Barakat on June 19, 2008 07:15 AM

Comments are fine, but maintainable code is so much more than just documentation.

I've had two sizable, heavily used codebases under my jurisdiciton, in my career so far. Lucky for me, the first was the very maintainable one. I learned a lot about the SDLC from that job.

Needless to say, the second codebase had several >1500 line sprocs that output... (wait for it)... html!

Also, I can't believe no one's mentioned Brian Kernighan's famous quote, "Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?"

Pat Farrell on June 19, 2008 07:56 AM

@Tips: this is the funniest comment I've read here in a while:

"I'm not really understanding your post or what it's aiming to!
I think you have to review some of the articles your are publishing here"

Steve on June 19, 2008 07:57 AM

Jeff, I certainly appreciate when you press the idea of best practices. However, let's all keep in mind that sometimes best practices have to take a hit from deadlines, stress, and bad management. Don't be so quick to curse the developer of the code you're struggling to maintain until you've coded several thousand lines in his/her shoes.

Granted sometimes even under the most favorable of conditions people churn out bad code. But even the best and brightest might produce code that's not up to their usual standard under certain circumstances.

Additionally, not everyone has really good peer mentorship. Some are learning as they code, developing best practices along the way (that's certainly the story for me!) Code they produced even six months ago isn't as pretty as the code they are producing today.

More blame is surely earned by the guy that's been programming for years and still produces sloppy code.

Just keep an open mind.

kenneth on June 19, 2008 08:00 AM

My first job in college was doing tech support on a small commerial product. Being a small consulting firm, I was able to teach myself VB and work my way into development there. My first few assignments were maintenance work on existing client projects. Unfortunately, I learned more about how _not_ to program and how painful unclear code can be to someone not familiar with it. To this day, I code with that pain in mind. As I code, I think about holding myself accountable to some imaginary maintenance programmer sitting next to me to whom I'm explaining the very code/comments I've just written.

That was priceless experience. Some of my coleagues have not had such experience and I can see it in the code they write; their whole approach to coding a solution.

In classic French kitchens, cooks didn't go to school to attain their position, they worked their way up from dishwashing, to prep cooking (cutting vegetables, etc.), to cook, to chef. Along the way they learned every detail, both good and bad, of every aspect of a functional kitchen. That depth of knowledge and wisdom can only be gained through personal experience.

Craig Boland on June 19, 2008 08:02 AM

In school they always preached to write good code and comment your code so the next person could maintain it.

Of course, if you want job security, write your code so the next person can't :)

Acctually that doesn't work so well... when you write something and then don't look at it for a few months, you might as well be that next person. And then you'll be kicking yourself for coding that way.

Kris on June 19, 2008 08:13 AM

I've never gotten angry because of code that I had to maintain but I've been profoundly saddened many times.

twmcneil on June 19, 2008 08:34 AM

I believe being able to read code is as great if not greater skill than being able to write it. Having been a team lead, I've given legacy code that is still in production to programmers to be modified. Sometimes the programmer will come back after a cursory examination and declare the code to all be crap and that it needs to be re-written, even for code that was well written and had been peer reviewed. What I learned over time is that some programmers are really good at reading code and others are not.

Kuerwen on June 19, 2008 08:41 AM

I always do this for code I'll maintain. Because it's true.

Tom Clancy on June 19, 2008 08:44 AM

I agree with Charlie Lobo that everything has its use, including GOTOs. Not that I use them often (once in the past year and a half), but I would argue that my use *improved* the quality and readability of the code I was writing.

I was working on a C routine to set up a serial port for later communication (open it, set the baud rate, parity, ...). Since there are so many API calls in that, and each one has the possibility for failure, I simply have all failed calls GOTO a failure label that cleans up (closes the port and returns a bad value).

The other options (in order of readability) would have been:
- call another function to do the cleanup and then return a bad value each time
- same cleanup in each place
- write a macro that does the cleanup and call it each time

I would argue that since the failure cleanup code was in a logical place (at the end of the function) and it was the only use of GOTOs (I wasn't trying to use them for looping or anything where better constructs already exist), that I made the best choice available.

That said, legitimate uses for GOTO are extremely rare and should always be well thought out (how else would I remember what I used it for and when I used it?).

Jon on June 19, 2008 08:48 AM

Jeff: Not entirely related to this post, but in the last two months, you had a post that discussed error handling on ASP.Net apps. (It might also have been on the stackoverflow blog.) You noted how it was the first thing you setup on a project, and it sounded like a neat tool.

I didn't note that open-source project with a horrible name at the time, and I've been trying to find it - but I can't find the post now, and can't recall the name.

Am I going mad?

Remi on June 19, 2008 08:52 AM

You should make one of those motivational posters out of this image (with the bold text included of course). That's the best line I've read in a long long time!!!

Stephane Grenier on June 19, 2008 08:59 AM

Picture scared the crap out of me. That's all I have to say.

Wayne on June 19, 2008 09:06 AM

Jeff, you scared my kids with that pic. now they're turbo crying. thanks a lot.

Jin on June 19, 2008 09:07 AM

>That said, legitimate uses for GOTO are extremely rare and should >always be well thought out (how else would I remember what I used >it for and when I used it?).

>Jon on June 19, 2008 08:48 AM

@Jon your solution was reasonable and correct. The next programmer will surely be happy that you didn't use some half baked 70's era feature from C such as setjmp/longjmp to solve the problem...

o.s. on June 19, 2008 09:12 AM

The problem of non maintainable code can only be solved if you take the onus away from the programmer who wrote it, who primarily, sees coding as his profession and not his hobby. Only a small percentage of programmers are truly passionate about what they do.

After all, 9 spoons of dirt + 1 spoon of pudding = 10 spoons of dirt.

It is impossible to get a decent percentage of the task force to comply with the comments rule for it to make a difference.

Make the computer do more (automation, dev environments, magic…). Make the coder do less.

Preeti Edul on June 19, 2008 09:16 AM

I make videos to explain what my code does and then just put a YouTube link for the comment.

Robert S. Robbins on June 19, 2008 09:39 AM

A little phoned in today, isn't it? :)

Promit on June 19, 2008 09:48 AM

For writing maintainable code you need to have roghly this order of priorities:

good design > well factored code > good variable, function, and class names > good comments (written at the level of intent & concentrated around the most complex elements)

Ideally you want to aim for self-commenting code first, which is code that is so well designed, so well factored, and uses such descriptive naming that just reading it is sufficient for others to understand it. Where that fails and ONLY where that fails, typically where complex or kludgy design elements are unable to be avoided, write good comments describing the tricky bits. Write comments at the level of intent, don't translate the code into English. Explain what the code is doing, for example: instead of saying "increment variable foo" say "keep track of number of retries", even better, use a variable name descriptive enough so that you know what the use is.

Also, avoid over commenting your code with obvious comments that add no value. This is a huge waste of effort on both the part of the commenter and the part of the code reader / maintainer, because it distracts from commenting the parts of code that need it the most. More so, commenting alone is not sufficient. You can't improve badly designed and badly written code much by expending great efforts to comment it, down that road is the way to turd polishing, sometimes refactoring (especially renaming) and rewriting is the only way to improve readability.

Robin Goodfellow on June 19, 2008 09:48 AM

As always, "Software is a conversation. Be Polite."

This applies to your source code as well as your interface, (source code being just another kind of interface).

I know courtesy isn't in, especially if you're younger, but no matter who you are, you'll be on the receiving end of someone else's work, or they yours. You can make it easy or hard. Your choice. Which would you like to deal with?

ThatGuyInTheBack on June 19, 2008 10:10 AM

This makes me wonder about something. If maintenance is "99% of the coding work in this world" (which I don't dispute), then why is 99% of the information and discusion in books, blogs, etc on the act of coding and designing and not supporting?

Mark Roddy on June 19, 2008 10:35 AM

@Mark, because the software industry is still young, because the state of education does not mesh with the state of practice in this field, and because it's easier and often more interesting to talk about designing. Consider that at most colleges the only route to software engineering is a computer science degree (not the same thing at all) and that it's possible to obtain a 4 year college degree in such without ever touching a source control or bug tracking system and without ever writing or using automated tests. Consider that the number of software engineers who do their jobs well and represent the best practices of the industry is a tiny, tiny percentage of the number of people who earn a living coding.

Robin Goodfellow on June 19, 2008 10:43 AM

Other people's code is crap. My code becomes "other people's code" within approx. two months.

Manu on June 19, 2008 11:10 AM

Now you scared me so bad that I'm going to "go dark". :P

Tommy on June 19, 2008 11:17 AM

The uses of goto are not rare. Most programmers use them every day, and don't even realize it. We've just given the generally accepted uses of GoTos special names to hide the fact that they are GoTos. Want an example, try the "Continue" keyword in .Net. In .Net 1.1, you didn't have Continue in VB.Net. So, if you wanted to accomplish the same thing, you had to use a GoTo. All of a sudden, as soon as they created the continue keywork, it was alright to just around to the next iteration of a loop. But if you had to use a GoTo, then it was wrong? I highly disagree. Same thing goes for "Exit For/While" statements. They are essentially gotos, but nobody says that you shouldn't use them.

There is no reason not to use GoTos, and sometimes you can make your code a lot more readable just by using them. Obviously you can use GoTo badly, and make spaghetti code using them. But the same could be said for any programming construct.

Kibbee on June 19, 2008 11:19 AM

I'm not recognizing where the image is from - let us know so I can put the film on my Netflix queue!

mikeb on June 19, 2008 11:40 AM

Production programmers where I work simply copy forward programs from old jobs and add to them; it's a nightmare, why don't people like clean readable code????

Dale on June 19, 2008 11:43 AM

Jeff must have taken that picture of me while I was programming one morning without my coffee!!

kenneth on June 19, 2008 12:10 PM

Now there's a good idea for a post! What are some things programmers do that give them a boost (best practices, eh!) I.E. coffee, soda, chewing gum, listening to music, etc.

kenneth on June 19, 2008 12:15 PM

I am interested to know which company would hire a programmer who looks like that.

Aaron Seet on June 19, 2008 12:20 PM

My favorite ever was when I had to re-write a legacy application that was written by a guy who had long moved into management.

I was totally lost as to what some items were supposed to be doing and I came across some really oddly named variables, so I started there and went upstairs to ask some questions.

Me: "Hey, what does the var coffeeCup do and where did that come from?"
Him: "Oh I can't remember that. But I did go through a period where I titled variables after THINGS I SAW ON MY DESK AT A GIVEN TIME."


Le sigh.

Ian Patrick Hughes on June 19, 2008 02:03 PM

I write crap code at times. I'll admit that. But at least I understand why.

Whenever I come up with a conceptually simple, elegant algorithm for solving a problem, I think of it executing visually, as though its a mechanical device chugging away. But, as they say, a picture is worth a thousand words. What seems so simple as an image/animation can be extremely difficult to describe in code (or in English, for that matter). This difficulty is what causes very poor-quality code to be written.

The only problem now... what do I have to do to overcome such obstacles?

KG on June 19, 2008 02:57 PM

I think a large portion of it is office politics.

You only have two weeks to write the program, but you can maintain it for years and that's ok.

Jeff Davis on June 19, 2008 03:02 PM

One of the things I find desperately sad is the number of people who believe these issues are about "style", "fussiness" and "cost-effectiveness".

When I tell someone code needs to be rewritten, it is not because it looks a mess or is confusing or I don't like the style: it *IS* a mess.

And I define mess as "it can be logically demonstrated that no matter what you do to it, it will never work, only appear to do so."

Take this, for example, as not altogether atypical "acceptable" and "cost-effective" coding where a rewrite is considered "offencive", "time-wasting" or "perfectionism" by management and certain members of the team...

--

MyFunction(Parameters...)

- Use parameters to calculate a percentage (incorrectly).
- Summarise percentage as three values, "Good", "Bad", and "Ho-Hum" (incorrectly).

'Bug fix added by programmer when she realises her code isn't working (this is *within* the same function, not elsewhere in the project)...

If MyFunction() = SomeAberrantValueObtainedDuringTesting Then
MyFunction() = HardcodedGuessedCorrectValue
End If

If MyFunction() = SomeOtherAberrantValueObtainedDuringTesting Then
MyFunction() = HardcodedGuessedCorrectValue
End If

etc...

End MyFunction()

--

This example is greatly simplified: there were a few spurious recursions in the percentage calculation and the If-Then statements which performed the hard coded corrections were deeply entangled within many self-contradictory layers and spurious recursions.

The errant belief that a function can be used as a variable to hold its own return value while being calculated through many partial steps was the least of this programmer's problems. Yet, this was accepted by management because it "appeared to work" when tested.

Add to this that such people are regarded as model employees while the rest of us are "troublemakers" and "less employable", it is a wonder that more of us don't become psychotic...

Paul Coddington on June 19, 2008 04:03 PM

BTW, it took 2-3 lines of code to replace that huge function with code that worked.

Paul Coddington on June 19, 2008 04:05 PM

*runs away scared*

That is, from both horrorshow *and* the poor coding!

John on June 19, 2008 04:21 PM

@Jon on June 19, 2008 08:48 AM
"each one has the possibility for failure, I simply have all failed calls GOTO a failure label that cleans up"

Sounds like the C equivalent of local exception handling, so probably quite a reasonable approach.

Two alternative approaches I've seen for that situation:

status_ok = apifunction1();
if (status_ok)
&nbsp;&nbsp;status_ok = apifunction2();
if (status_ok)
&nbsp;&nbsp;status_ok = apifunction3();
...
if (!status_ok)
&nbsp;&nbsp;cleanup();

Or even simpler using short-circuit evaluation:

status_ok = apifunction1();
status_ok = status_ok &amp;&amp; apifunction2();
status_ok = status_ok &amp;&amp; apifunction3();
...
if (!status_ok)
&nbsp;&nbsp;cleanup();

Both seem just as clean and don't use the "dreaded GOTO".

Graham Stewart on June 19, 2008 05:51 PM

One of the ironies of life is that our Indians (mostly 20-somethings) are sent off to "maintain" 30 year old COBOL code so that Our Employer (a Fortune X00 company) can keep all those other Fortune X00 clients locked in. What goes around comes around. The Cream of IIT learning the stinky habits of dead white guys. And this is truly cruddy code. I suspect that much of the touted Indian Uber Menchen are doing just that.

And this is the evil side of "accepting" being a maintenance programmer: one gets assimilated into shit. After a while, if you've got the spouse, and the kids' braces, and the vacations, etc.; meh, it's a living. THAT's where truly evil code comes from.

buggyfunbunny on June 19, 2008 05:57 PM

Jeff-

How did you get a picture or our co-worker?

By the look of many code bases out there, there's probably several people that are one or to "gotos" away from turning into this guy.

Most places are get it out now, worry about it later. That combined with employee turnover and offshoring leads to some pretty cryptic situations.

I always hum "On top of Spaghetti, all covered with bugs, I lost my poor data, it all covered with crud..." to myself to keep my sanity while debugging through the lines of someone else's craptacular code.

Getting up and going for a walk always helps out as well.


Jon Raynor on June 19, 2008 06:19 PM

I'm surprised no one's pointed to <a href="http://www.web-hits.org/txt/codingunmaintainable.html">How to Write Unmaintainable Code</a>

pookleblinky on June 19, 2008 07:33 PM

"Any of your code that you haven't looked at for 6 or more months may as well have been written by someone else" (can't remember the name of the person who wrote it but its true in my experience)

And I agree with the sentiment that well written code should be fairly self-documenting. What I like to see in the comments is an explanation of any dependencies and business rules relating to WHY the code is implemented in that fashion. Your code tells me what you did, comments should explain the non-obvious.

Campbell on June 19, 2008 08:54 PM

Bad code is fun to refactor; now how do those unit tests look for testing that I haven't broken any business rules... What NO unit test, now where's my axe!?

bloop on June 20, 2008 12:57 AM

GOTO lives on, just today it's called 'break', 'continue', 'throw', etc...

Tim S on June 20, 2008 01:21 AM

Never install the Java Decompiler, JAD, and look at the library code you are dependent on.

Just don't.

If you do, however, never run the FindBugs utility (which I recommend for all lazy code reviewers btw) against the decompiled code.

Just don't.

Or you will cry.

I've picked up lots of code in my time, and the hardest stuff was Java "o-o" code, because everything is buried so deep and bugs very hard to find. Oddly, Ruby is easy to debug once you've understood how metaprogramming works and it *is* an o-o language. But most of the time you just write code to do what you need to do and write tests for that small thing.

UML etc. etc. - guys you are working at the wrong level. UML blah ... once you've gone past the initial system design it's another thing to maintain and it won't be. Throw it away and make the code base clean. I'm very old fashioned - I tend to start from a clear data model and view the rest as just a layer on top of it. I don't care about the class model - it's usually not worth worrying about and a lot of code is procedural code hidden in static classes anyway - be honest, now. This is particularly true if you are using an o-o to relational mapper - that's where all the complexity is and you have decided that you want the mapper library to do the work. Data matters, the rest is fluff.

I also recommend finding a formatter for the language you are using if you are trying to understand someone else's code. It's amazing how many bugs you find when the formatter changes the indentation to reveal what the compiler/interpreter will *actually do* with the code.

Read Fowler's refactoring book, even if you are not a Java programmer, it repays close study.

Old frt signing off now.

Francis Fish on June 20, 2008 01:35 AM

I have to maintain certain programs just working on my own pretty much and did actually meet the programmer. I asked him about documentation/comment his excuse was the code documents itself. Great

there is so much useless/old code that is now defunct here comes a rewrite

pete on June 20, 2008 02:10 AM

Jeff, I really enjoy reading some of your stuff, but man, you got to learn one thing: if you don't have a good idea for a blog entry, don't submit a bad one, PLEASE.

Tudor on June 20, 2008 02:19 AM

I agree with the article's sentiment but not all of these comments.

Comments can be useful but if they're wrong then they're mis-leading.
So they aren't just good++great as some people here are stating.
Don't write comments that can get out of date easily. And don't write undocumentation as that's just a waste of everyone's time and makes me angry (growls at GhostDoc):

i.e.

// gets somename
public string SomeName
{
get{}
}

I'd rather the comments just give the intent of the code.

// this class is here to make problem x
// architecturally simpler because of abc
public class SomeClass
{
}

As opposed to any implementation details (apart from maybe commenting hacks, oddness in lower levels/hardware or seriously odd semantics).

// for some crazy-ass reason we
// have to wait for a bit or otherwise
// the next call wont work
Thread.Sleep(100);
DoNextCall();

We have metadata to comment with as is. Variable names, method names, class names. These should be the primary forms of commenting your code.

The biggest crime for unmainability is copy + paste and people not tidying after heavily modifying classes.
Commenting out code is another one, we have source control! Just delete the code if it's no good otherwise there is too much noise to easily make sense of whats going on.

Stick to the coding guidelines, do not duplicate code or create parallel logic paths that basically do the same thing but create two maintenance spots and refactor as you change. Those principles are much more important than comments.

Jax on June 20, 2008 02:20 AM

> A little phoned in today, isn't it? :)

People complain when the posts are too long.. people complain when the posts are too short.. let me think, what's the constant value here? :)

Jeff Atwood on June 20, 2008 03:59 AM

Boy, I hate the picture. Now I need to skim porn sites to get that off my mind. :-)

The best way to make your code easy to maintain is to keep it simple. Ideally, so simple it does not need any comment whatsoever (through good choice of variable and function names, no "smart" techniques, function that does only one thing and does it well, abstraction, modularity etc.) Use comment only if it adds value. If you can speed-read (accurately) a piece of code without looking at the comment, then delete the comment. If not, then keep the comment. But if you cannot understand the code even after repeated read, delete the code and write a better one. Make sure you have the authority to do this, though. :-)

Paulus on June 20, 2008 05:15 AM

> what's the constant value here?
"people complain when the posts are too"

[d3m0n] on June 20, 2008 05:20 AM

Heh, when I read title of this blog entry, that quote was the first thing that came to my mind...who knows why :-]

eS on June 20, 2008 06:06 AM

Jeff the constant is (in VBS)

' Below is the constant set to ensure we treat all customers the same
' if we assume customers will not complain we will be disappointed,
' however if we assume they will complain, but then they do not
' and perhaps are even happy, then we are pleasantly suprised.
'-------------------------------------------------------------
Const USERS_COMPLAIN = 1

Scot McPherson on June 20, 2008 06:26 AM

On the use of break/continue... Like goto they should be used sparingly. The upside to them is that they are more specific than a goto, i.e. you can't really create infinite loops with them and fun stuff like that, but they do help create spaghetti code.

I remember way back in programming 101 the first thing my instructor said about break and continue was "don't use them". Usually when you find no other way, it's a clear sign there's something wrong with the way you set your code up and it would probably work lots clearer and better if you refactored the code a little so you don't need to do all sorts of tests in the middle of it.

wds on June 20, 2008 06:38 AM

@Jeff Davis...

Common name, I realize, but I am wondering if you are Jeff Davis that used to work for Insurance Technologies Corporation in Carrollton, TX.

If so, I know you. Dream Theater Rocks!!!

WA

Wayne on June 20, 2008 09:13 AM

Flipping around a program in a speed reading code review, some of the code looked very familiar. Then I saw:

/* If you do not understand the semantics of the communications return codes or the protocol as used by the partner program, do not change this page of code */

:

code

:
/* END OF: If you do not understand the semantics of the communications return codes or the protocol as used by the partner program, do not change this page of code */


The program was, in part, an nth generation mutated clone of something I had done a decade before. The comments had successfully inflicted sufficient FUD. The code between the comments had not mutated at all.

David

DAKra on June 20, 2008 09:33 AM

I am currently porting some SPEC benchmarks to Mac OS X and even the SPEC code isn't too well written. Some "maintenance" on it would definitely make 'em run faster than better hardware.

- jay

Jay on June 20, 2008 09:52 AM

If we write our code perfectly, then do we really have to comment it? Doesn't this just give lesser developers the ability to pick up where we left off? Where is the job security in that?

JobSecurity on June 20, 2008 12:53 PM

I wish more developers would consider this. I recently took on a website maintenance project for a transportation agency - the system is a custom-designed CMS that is so poorly implemented it requires a programmer to add a new page! I spent MANY hours rewriting the fare system just to handle a simple fare update.

Documentation? Practically non-existent. Comments in the code? yeah, right. Good coding practices are not even attempted (such as naming and use of variables and functions). And talk about spaghetti code - it's almost impossible to follow.

What makes it worse is the original developer's site says such things as "an award winning development firm", and they've received awards like "Entrepreneur of the Year".

They're really good at marketing. They're really lousy at delivering quality code. But, unfortunately, the quality of the code doesn't matter at all to the businesses that hire such developers - so those of us who actually care about such things are going to have to keep dealing with this crap for a very long time.

BTW - I don't usually do this, but in this case, the code was SO bad, I actually quit the project.

Tony on June 20, 2008 01:09 PM

"A very good habit I was taught in university was to comment first, code later. What approaching a programming task, write out the comments for the code that you haven't written yet. Helps you plan and you end up with detailed comments when you're done."

That's why I love languages like Ada where you are more or less bound to write the interface first. If you do your comments in the same way, obvious design flaws show up, before you even started to implement the code.

Well, in the current C-Code I am thrown in to maintain it, it seems to be tending the other way around. First the code was written and then some interface (.h) was hacked together. The only comment in the header files usually is the copyright notice, everything else is just the list of subroutines that happen to be in .c file. I'm always thinking what a waste, nobody would steal that code anyway. ;)

The most problematic thing for the maintenance programmer with such code is that he is forced to look at the code (where are sometimes the functions are even explained to some extent) to figure out what a function does and then you tend to ignore any comment anyway, because the code is much easier to read. ;)

But beware, it can make a huge difference between what a function actually does and what is was supposed to do. Reverse Engineering at its best and that's where I definitely agree with Jeff - you need smart people to do that kind of job and not some junior programmer who has barely touched any real world code yet.

Oh, last but not least, about the most "funny" thing: Some stupid prick (pardon my french) sometimes even documented the interface that way:

/*
* Input : int Some_Parameter
* Returns: TRUE or FALSE
*/
BOOL Something (int Some_Parameter)

Hell, yes. I can see that from the prototype. But what does it actually _DO_?

Vinzent Hoefler on June 20, 2008 01:21 PM

Jeff

Who gave you permission to post a picture of one of my users on your site? (ok so they all look like this)

Steve on June 20, 2008 01:56 PM

That mental assault was really unnecessary!

B on June 20, 2008 02:34 PM

@Tim Almond
That's not my point at all, for me this quote means "write quality/maintainable code even if it feels like a hassle or you are going to be murdered" and my point was that changing "be murdered" by "clean a spaghetti code mess" was more motivational.

ilcavero on June 20, 2008 11:55 PM

In my experience, besides sensible comments, sensible naming conventions for packages, classes, methods, etc., sensible project layout and code formatting are paramount to achieve code maintainability. All this, of course, must be agreed upon by the team. Now, the problem problably is to find an agreement on the meaning of 'sensible' :)

Federico Grilli on June 21, 2008 11:45 AM

My rumination on this is "Code should be written for humans, the machine can always be made to read it." In maintaining code, the compiler can read any crud and make enough sense of it to 'work'. The true issue is if a human can look at a page and instantlly know what's going on. For example seeing a case or casscading if then in a simple clean block "Oh, that's were the action is determined. The new one goes in here."

My worst face in the desk was a Russian "Don't question it works." He goto'd in and out of a called procedure that called the procedure again on one of the excursions out on a goto. I disassembled the machine code just to figure out why it ever worked at all. (No stack overflows, access violations etc it ran thousands of transactions.)

AL Pareigis on June 21, 2008 11:56 AM

Jeff,
I believe that Comments are important as much as the code that works(Hoping that Codes do work ALWAYS)...But sometimes overcommenting can also be a disaster..I hope you guys have never came accross nething of such kind..But i hve...

i hve a few 1000 lines of codes which is 50% Code and 50% Comment...Ever Imagine, how difficult it wud be to read the codes when there are comments for every line of Code?

Its worst then hving no Comments...Trust me on this...i hve Gone through this.

Ruvi on June 22, 2008 10:13 PM

It is a great photo! Project managers can use it for programmers who are too lazy)

Else on June 23, 2008 07:38 AM

I like this article so much that I took the "always code as if..." part, put it together in a document along with a picture of Gollum from the Lord of the Rings trilogy, and posted on the wall outside my cube.

VegeBrain on June 23, 2008 09:11 AM

We are the borg...
Refactoring is inevitable'.
You will be frustrated...

Mac on June 23, 2008 11:36 AM

I read tour tweet but don't think you're gonna do a blog post too.

By the way nice picture :)

kmilo on June 23, 2008 01:53 PM

netflix queue emptys
sadly, the chick flick arrives
the ghoul still unknown

mikeb on June 25, 2008 12:16 PM

Documenting code is important. But the big problem with documented code other than the inevitable change not being updated in the docs is that it doesn't document the protocol for using it. I consistantly see functions that are part of a larger chain of events with no consistant clues regarding when and how they are to be used. I'm a big fan of software that has been designed and that design documented. I've left a fair amount of it behind me, but have almost never seen it going into a project.

As far as writing code goes I prefer clarity over everything. On most modern systems the tricks I know to make code run faster just aren't as necessary as they were back when I wrote my helloworld. I've been writing code since 1974. Back then you needed all of the tricks to fit into memory and make things work fast. Much of that is now just academic farting around. My pet peeves involve programmers who depend on things like operator order of precidence for their code to work correctly.

The first big thing I wrote was a twisty maze of stateful code with lots of goto statements. It worked, but the first maintenance cycle required a complete rewrite because _I_ couldn't figure out what I had done. We do get better over time...


Sam Robinson on August 9, 2008 07:29 AM

I can't believe (If I'm wrong forgive me, I tried to read all comments first) That no one else has picked up on possibly the best comment on a blog ever

Andy Wong you are awesome.

Everybody please read the second comment to this entry.

Then read it again.

It is absolutely the best

Red on August 16, 2008 05:48 PM

I have felt the pain as well but,

I began my career as purist and nearly threw in the towel from endless arguments. The bottom line is our work costs money, and cost results in pressure from management, which will always result in shortcuts being taken - ALWAYS - so going on about it will only result in destroying relationships with the people who can advance your career and renumeration.

Also fixing annoying code takes longer - so more money - most people want pay you twice as much to do it right the first time, but will hardly bat an eyelid forking the money out for maintenance. Poor code is a cash cow - dont mess with it :)

Always remember were in it for the money (enjoying solving its puzzles is a just a bonus) and that pride goeth before the fall.

IsItReady on October 1, 2008 09:05 AM







(hear it spoken)


(no HTML)




Content (c) 2008 Jeff Atwood. Logo image used with permission of the author. (c) 1993 Steven C. McConnell. All Rights Reserved.