My Secret Life as a Spaghetti Coder
home | about | contact | privacy statement | getting started with cfrails
Just two years ago, I was beyond skeptical towards the forces telling me that comments are worse-than-useless, self-injuring blocks of unexecutable text in a program. I thought the idea was downright ludicrous. But as I've made an effort towards reaching this nirvana called "self-documenting code," I've noticed it's far more than a pipe dream.

The first thing you have to do is throw out this notion of gratuitously commenting for the sake of commenting that they teach you in school. There's no reason every line needs to be commented with some text that simply reiterates what the line does.

After that, we can examine some seemingly rational excuses people often use to comment their code:
  • The code is not readable without comments. Or, when someone (possibly myself) revisits the code, the comments will make it clear as to what the code does. The code makes it clear what the code does. In almost all cases, you can choose better variable names and keep all code in a method at the same level of abstraction to make is easy to read without comments.

  • We want to keep track of who changed what and when it was changed. Version control does this quite well (along with a ton of other benefits), and it only takes a few minutes to set up. Besides, does this ever work? (And how would you know?)

  • I wanted to keep a commented-out section of code there in case I need it again. Again, version control systems will keep the code in a prior revision for you - just go back and find it if you ever need it again. Unless you're commenting out the code temporarily to verify some behavior (or debug), I don't buy into this either. If it stays commented out, just remove it.

  • The code too complex to understand without comments. I used to think this case was a lot more common than it really is. But truthfully, it is extremely rare. Your code is probably just bad, and hard to understand. Re-write it so that's no longer the case.

  • Markers to easily find sections of code. I'll admit that sometimes I still do this. But I'm not proud of it. What's keeping us from making our files, classes, and functions more cohesive (and thus, likely to be smaller)? IDEs normally provide easy navigation to classes and methods, so there's really no need to scan for comments to identify an area you want to work in. Just keep the logical sections of your code small and cohesive, and you won't need these clutterful comments.

  • Natural language is easier to read than code. But it's not as precise. Besides, you're a programmer, you ought not have trouble reading programs. If you do, it's likely you haven't made it simple enough, and what you really think is that the code is too complex to understand without comments.

There are only four situations I can think of at the moment where I need to comment code:
  1. In the styles of Javadoc, RubyDoc, et cetera for documenting APIs others will use.
  2. In the off chance it really is that complex: For example, on a bioinformatics DNA search function that took 5 weeks to formulate and write out. That's how rare it is to have something complex enough to warrant comments.
  3. TODOs, which should be the exception, not the rule
  4. Explaining why the most obvious code wasn't written. (Design decisions)
In what other ways can you reduce clutter comments in your code? Or, if you prefer, feel free to tell me how I'm wrong. I often am, and I have a feeling this is one of those situations. What are some other reasons you comment your code?

Update: I forgot to mention that discussions on relatively recent blog posts by Brian Kotek (Don't Comment Your Code) and Ben Nadel (Not Commenting and The Tipping Point of Poor Programming) got the creative juices flowing in my brain for this post. Thanks for bringing it up, gentlemen.

Hey! Why don't you make your life easier and subscribe to the full post or short blurb RSS feed? I'm so confident you'll love my smelly pasta plate wisdom that I'm offering a no-strings-attached, lifetime money back guarantee!


Comments
Leave a comment

I'm trying to use Eclipse features like bookmarks, TODOS, etc to reduce the need to useless marker comments.

Posted by Jim Priest on Jun 18, 2008 at 08:38 AM UTC - 5 hrs

I find comments most essential when I am doing something counter-intuitive. For example, if I working around a bug (and therefore adding extra code that shouldn't be needed to accomplish a task).

In cases like that, I put code to say something to the effect of "Version XX of YYY has a bug that requires me to do ZZZZ to prevent AAAA from happening."

Posted by Steve Bryant on Jun 18, 2008 at 10:05 AM UTC - 5 hrs

intention. i can't tell you how many times i've read someone else's code, and have no idea why they did what they did. i've found countless bugs based on the comment with intention. perhaps they shouldn't have been there to begin with (the bugs), but they are extremely helpful in understanding the why.

i know its silly, but i still use crimson editor over an ide. i've tried eclipse, but i haven't had the tmie i need to get comfortable with it. that's cool that it does todo's. i wish that version control would take care of things such as that. i also wish that the comments we apply would remain with the code in some form as well. i think comments can be enhanced (at least in SVN) beyond where they are.

Posted by shag on Jun 18, 2008 at 10:32 AM UTC - 5 hrs

Times I still feel comments are valuable tend to be times I don't want the next reader to think I was just being obtuse:
-working around a bug, as Steve noted
-doing something peculiar to emulate legacy behavior (bizarre wrapper functions to preserve an old API signature, etc.)
-data contortions when working with database structures controlled by some other application

The common thread? They're rarely about HOW something is done, instead covering WHY something was done as written. Then it's easier to evaluate whether something strange needs to remain in the future -- if a wrapper function is labeled as needed to get the function signature just right for interacting with FooCorp's reporting module, then we'll know it's disposable if we've migrated to BarCorp's reporting module.
-CPC

Posted by Chris on Jun 18, 2008 at 11:24 AM UTC - 5 hrs

@Steve,

I agree. Well written code can be all that's needed to understand what something does, but the why is not as easily grasped in every situation (bugs is third party code/modules etc. is a perfect example)

Posted by Ryan McIlmoyl on Jun 18, 2008 at 11:27 AM UTC - 5 hrs

Honestly I find this hard to believe that comments are bad. The real problem is people write unhelpful comments...

Take this for instance:
<cfloop condition="patArr[patIdxEnd] NEQ '*' AND strIdxStart LTE strIdxEnd">
<cfset ch = patArr[patIdxEnd] />
<cfif ch NEQ '?'>
<cfif ch NEQ strArr[strIdxEnd]>
<cfreturn false />
</cfif>
</cfif>
<cfset patIdxEnd = patIdxEnd - 1 />
<cfset strIdxEnd = strIdxEnd - 1 />
</cfloop>

What is this doing? Well, you wouldn't know since I took all the comment out and even in the larger context of this snippet -- it would be difficult to figure out. Yea, you could describe what is going on and which counters are getting popped, but what exactly is this logic trying to accomplish?

I think what you are getting it is people commenting on stupid stuff like this:
<cfif shouldDoThis>
<cfset x = y />
</cfif>

Maybe it's because I've been doing a lot of work in areas that are very abstract code wise and so you have to comment in order to figure out where you are, otherwise you just have a bunch of loops and counters...

Posted by Peter J. Farrell on Jun 28, 2008 at 04:57 AM UTC - 5 hrs

@Peter, certainly comments themselves are not evil - the people who impose unhelpful and downright false comments on the rest of us are the (often unwitting) evil doers. =)

But regarding the code you posted above: with all due respect, the reason I can't understand the purpose of the code has little to do with the lack of comments. There are several problems with the code.

It looks like part of a regex engine. If it's not (or not something similar), those are atrocious variable names. Even if it is, I still think the code could be clearer (and I'd wonder why you're implementing it in CF =)).

If you don't mind, I'd like to ask a few questions and create a blog post out of my response:

1) Why are we stopping when patArr[patIdxEnd] EQ '*' OR strIdxStart GT strIdxEnd?

2) Why are we returning false when ch=="?" and ch!=strArr[strIdxEnd]?

3) What /is/ the overall purpose of this code block?

4) What is the significance of * and ?

Posted by Sammy Larbi on Jun 28, 2008 at 09:55 AM UTC - 5 hrs

Todo comments really don't belong either. How often do they sit for months or even years before eventually being deleted? If it really needs to be done then do it. If you can't get to it this minute then throw an exception that crashes the program with the descriptive text "to do"

Otherwise forget about it. You're just kidding yourself and adding clutter.

Posted by Bill Robertson on Jul 07, 2008 at 09:33 AM UTC - 5 hrs

@Bill - you're right. In a recent project I did make it throw an exception in a spot that /really/ needed to be done. Sometimes though, I do like to put in reminders where doing the to-do at the moment I realize it would break my train of thought on another item.

Even then, perhaps it would be better to keep that list in my text file than the code.

Thanks for pointing that out, I think I'll try it more often, because as you say, oftentimes those todo comments just sit around and never get done.

Posted by Sammy Larbi on Jul 07, 2008 at 09:47 AM UTC - 5 hrs

In an ideal world your points are pretty valid, however, commenting can be a really good choice sometimes:
Most people are not using your build of your IDE, and thus do not have your helpful bookmarks set up;
You are probably not going to be working within one code base your entire life and what is obvious/best practicey to you may be kludgy to another equally qualified programmer;
Other people sometimes need to know why you made a specific change and searching in the repo for a version where you made a specific change is much more difficult than finding it on top of the relevant code section

That said I rarely use comments beyond the debugging/prototype stage, but certainly wish others had sometimes ;)

Posted by Kate on Jul 07, 2008 at 11:05 AM UTC - 5 hrs

I agree - we use TDD and one of its main premises is to use the tests as a form of code documentation, removing the need to document code. It does work in my opinion.

That said there's still the odd //HACK laying about :)

Posted by Antony Koch on Jul 07, 2008 at 11:08 AM UTC - 5 hrs

First of all, I'm 100% behind the sentiment of writing clean, obvious, self-documenting code.

Having said that -- I develop firmware for deeply embedded systems, mostly in C and assembly, and often I'm working on devices drivers and such where I'm writing to hardware registers, etc... I'm working around undocumented chip errata, special intialization sequences, code segments with extremely particular timing & ordering requirements, etc...

In these cases, I ask myself, "if I or anyone else came back to look at this in a week, would this code cause any head scratching?" If so, comment/explain why this code has to be here.

So that's my answer to your question "In what other ways can you reduce comments in your code?"

Posted by Dan on Jul 07, 2008 at 11:10 AM UTC - 5 hrs

I agree. The main solution here is good version control and proper naming of methods and variables. If the code works, which it should if committed, then it should be relatively easy to understand. However, if there are bugs, comments may be necessary, but ideally no code with bugs should ever be committed. Even with JavaDoc I find it difficult to write a comment describing a class or method that isn't already obvious from the name of the class or method

However, with that said, I have also encountered much code that has been poorly written with bugs, poor variable names and method names and poor levels of abstraction. When this is the case, comments can be essential in understanding the code.

Posted by Anonymous on Jul 07, 2008 at 11:18 AM UTC - 5 hrs

While often inane and gratuitous, comments are still quite useful in explaining the "why" of what's going on. By definition, programming languages are written for computers, to be parsed by compilers and interpreters. Comments are written solely for humans. I'd much rather have an excess of the human variety than try to become the parser. One coder's perfect function is coder's completely obfuscated lump of text. The difference between the two is a bit of a human language narrative explaining why it's there in the fist place.

Posted by Lex on Jul 07, 2008 at 11:39 AM UTC - 5 hrs

I couldn't agree more! If you code needs commenting, you should ask why...

Another note of why commenting can be bad, comments are rarely refactored so what happens is that over time the comments no longer reflect the code. On top of that, often the comments move from their original position to where they're no longer even near the original code they once commented.

The biggest way to avoid comments is to abstract. If the code is too large, then write a method. You want to be able to focus on the layer you're working on, not extra things. So for example if in the middle of your function you write some code to reverse the order of a string, then "Extract Method" that code. Get it out. It's on the wrong conceptual layer. Pull it out into a function. The code will be much much more readable than adding a comment that says it reverses the string!

Posted by Stephane Grenier on Jul 07, 2008 at 12:25 PM UTC - 5 hrs

I can think of one thing way worse than superfluous commenting: blindly adhering to dogmas. There's only one good rule for commenting code: use common sense.

Furthermore, I seon Lex' comment: the main reason for me to use comments is to explain the 'why' (for myself as much as for others). Code itself, however readable, doesn't tell the "why", just the "how", because that's all the computer needs to know.

Posted by Rick on Jul 07, 2008 at 03:16 PM UTC - 5 hrs

let me share some of the reasons why we comment..

one of the reason is deadline.. where it can force us to do something like:

# FIXME: need to optimize this to blah blah blah(w/c requires a bit more work) so that it can be faster. do the fix when all the task i have are all minors or the need to optimize this will be major.
def search
#the lousy search code
end

and also, dependency:

# NB: replace with the do_this module when it's done by the other guy
def do_this
#for now, do the do_this lousily
end

we also use it to spot some mistakes our teammates did.

# FIXME:FIXME: stephen to other guy. why do we use the part where blah blah blah? can't it be done with blah blah blah instead so it can be better?
def test
#some code that was implemented lousily
end

also, when we are touching the modules of our teammates, we comment so that they don't get shocked/offended why their code changed..

Posted by stephen on Jul 07, 2008 at 10:22 PM UTC - 5 hrs

Right. I agree. clean-clear code explains better than comments stuck to ugly code. Statistically, I found much more comments (dispersive and pointless) in spaghetti code than in well-done projects. Therefore, I assume that the more developer write mess code, the more verbal (and tedious) comments will lay down

Posted by Giancarlo Frison on Jul 08, 2008 at 03:41 AM UTC - 5 hrs

Hi, I've written something on this:
http://itscommonsensestupid.blogspot.com/2008/03/o...

Posted by Ngu Soon Hui on Jul 08, 2008 at 04:30 AM UTC - 5 hrs

Sometimes I write the comments before I write anything else. The high level pseudo code in the ocmments keeps me focused.

Otherwise, yes, crystal clear code is better than comments.

Posted by Bob on Jul 08, 2008 at 10:04 AM UTC - 5 hrs

I have two audiences when I write code.

The first would be the computer system that acutally has to use it. It doen't care about comments or formatting.

The second much less important audience is the next Developer that might have to modify my code. I use proper intenting to make the code itself more readable, but addings inline comments in my native tounge is not something that I do. The key word here is Developer. One that is a Developer should not need a Code -> English translation since they are supposed to already be fluent in Code.

What the code is supposed to do and how it does it belongs in a systems Documentation (I know its four letter word for many), not in the code itself.

I'm not trying to hurt anyones feelings here and I know I come across as a hard a** when I say this (someones gotta be right?), but if you need comments to figure out what some block of code is doing, the lack of comments is least of your problems...

Posted by Scott on Jul 08, 2008 at 10:26 AM UTC - 5 hrs

While it is good to avoid commenting things that are painfully obvious, it would be good to comment things like this:

map$i+=$_,1..pop;print$i,$/

Posted by SeanJA on Jul 14, 2008 at 11:41 PM UTC - 5 hrs

@SeanJA: Of course, it may be better to just not write code like that in the first place, if readability, understandability, and maintainability are anywhere near the top of your list of goals. =)

Posted by Sammy Larbi on Jul 15, 2008 at 11:10 PM UTC - 5 hrs

Pretty, self-documenting code is easier for humans to deal with, however, computers have to deal with the program too.

Performance is sacrificed for readability. There's nothing wrong with that, we all do it, just keep in mind that you're doing it too. If you put a greater emphasis on writing pretty code, you're probably losing even more speed. There's no excuse for terrible variable names and excessive comments, but keep in mind that beautifying code can be taken too far.

While it usually isn't a problem, sometimes the pretty, self-documenting way of writing something is really slow. Or, it may be the case that a really fast way of doing something is ugly. If so, write it the performance-friendly way and put a comment in there.

Simply put: I don't want to have to figure out what your inline assembly is doing, but I'm sure glad you wrote it that way because it speeds things up. Sometimes ugly is beautiful.

Posted by Rob on Jul 16, 2008 at 09:42 AM UTC - 5 hrs

Ok, here I go disagreeing with you guys.

These points reflect what would be done in an ideal world. And 2 years ago, I would agree with everything said.

HOWEVER, after working on a Monster of a project for the past two years, I've began yearning for comments in code. A lot of my work deals with bug fixes in existing code and I've finally quelled my urges to simply rewrite crap that doesn't work. Here are my reasons:
- Sometimes past developers were just simply bad and there's no 'time' to refactor.
- Significantly modifying (and trust me, a lot of the modifications needed would be significant) would require retesting that functionality in the QA department. In an environment where time = money, that just isn't a viable option.
- Comments are usually frowned upon where I am ("They get in the way", I've been told). So the alternative is to sit (sometimes for hours) debugging trying to figure out what's going on.
- In my environment, the 'weird' parts of the code usually deal more with business logic and less with actually functionality. When there's a statement that says: {if A = 'CPTY'}; I'm sorry, I need a comment. Because walking over to the support department to ask "what's CPTY" isn't my idea of the best use of my time.

So, what does one do with messy code when refactoring isn't an option? I say, comment the hell out of it.

Posted by Baz L on Jul 25, 2008 at 12:52 AM UTC - 5 hrs

I think using pragmas (talking about C) for debugging purpose is an option to commenting debugging code.

Posted by Ricardo on Jul 25, 2008 at 01:17 AM UTC - 5 hrs

Baz: Of course, if you work with a project that is not well factored, comments are helpful. The important point is that well-factored code shouldn't need comments to explain what it does. If working on badly factored legacy code, it can be helpful to comment code once you understood what it does. Refactoring that code is a better alternative, but not always feasible.

Posted by Sebastian on Jul 25, 2008 at 04:47 AM UTC - 5 hrs

Comments are like handshakes, it tells you a lot about the other person you are working with.

Posted by Stander on Jul 25, 2008 at 04:51 AM UTC - 5 hrs

Here's a good reason: business logic. I'm a good programmer - a seven, maybe an eight on my good days - but regardless of how well I am able to comprehend what a block is doing, it will never communicate it's larger context, nor the underlying business logic that (hopefully) drives the process.

Posted by Corey Furman on Jul 25, 2008 at 09:14 AM UTC - 5 hrs

hey sammy, i thought it was rad that jeff atwood quoted you on codinghorror: http://www.codinghorror.com/blog/archives/001150.h...

yer famous, son!

i will say that i find myself, even now, having comments in code because i wrote the comments first as a form of pseudoprogramming. I'm sure this is a holdover from my procedural way of doing things, and as I do more TDD I find this happens less often

Posted by marc esher on Jul 27, 2008 at 08:21 AM UTC - 5 hrs

@Kate: If you're version control system can't easily tell you when a particular line was last changed, you need to change version control systems, not work around it by putting changed-by-so-and-so comments in your code.

Posted by Matijs van Zuijlen on Jul 31, 2008 at 09:54 AM UTC - 5 hrs

@Matijs van Zuijlen
The frustrating thing is that the people using these things aren't usually the ones making these decisions. And for very good reasons (usually tons of history), version control can't be easily changed.

A lot of the things which would make things better (good ver. control, refactoring, writing good code) are usually out of the hands of the lowly developer that's just trying to wade through the thing.

Thus the problem with managerial decisions.

Posted by Baz L on Jul 31, 2008 at 12:59 PM UTC - 5 hrs

Great article. A concise summarisation of my exact views and experience. The most successful product I have ever worked on adhered to self-documenting principles. It is a 7 year old perfomance critical embedded C++ project, and it is as maintainable now as it was at the start.

All arguments I have ever heard against self-documenting code have been woolly non sequitors, mostly from people who have never tried it or even read up on it.

“The existing code is bad and it is too risky to refactor” – so it isn’t self-documenting code – so that doesn’t mean self-documenting code is bad. Fine, add comments to the old code, but from now on do it right (and add some automated tests while you are at it)
“I don’t want to sit for hours figuring what is going on” – then write self-documenting code
“The code is full of domain specific abbreviations” – if you were writing business logic you would clearly benefit from understanding the language of your domain. If there isn’t a product glossary then start one. It will be quicker than adding the same comment to explain the same abbreviation all 568 places it appears in the code.
“I need to document my API so my clients can understand it” – yes, I never said you shouldn’t

Of course, the most spurious and commonly used counter-argument is from the person who puts forwards a piece of unintelligible, uncommented code and points out that adding comments would improve its readability. Yes they would, but so would refactoring it to make if self-documenting. It is better to use liberal comments or write self-documenting code than to do neither. But a piece of code that does neither clearly does not prove that liberal comments are better than self-documenting code. The only proof of this would be examples of the same piece of coding logic, written firstly with comments, and secondly as self-documenting code. I could produce dozens of such examples off the top of my head which demonstrate multiple compelling reasons why the self-documenting code is superior.

Posted by Simon R on Aug 15, 2008 at 12:54 PM UTC - 5 hrs

Don't get me wrong, I'm totally for self-documenting code. But when you work in an environment where you need to justify ANY coding change you make (refactoring or otherwise) that isn't for the purpose of "fixing a reported issue", then comments are the only sure way to prove (to a higher authority) that you didn't change the logic and still have some sort of readability.

Posted by Baz L on Aug 15, 2008 at 02:37 PM UTC - 5 hrs

Baz L, But a comment isn't a sure way to prove anything. You can say what ever you want in a comment. If that is how your bosses are "proving" things, I have some fuctions that do some spectacular things to sell them :).

"Needs Refactoring" is a completely valid issue. If you need a service request to fix it, report it yourself.

Posted by Scott on Aug 15, 2008 at 02:55 PM UTC - 5 hrs

Leave a comment

Leave this field empty
Your Name
Email (not displayed, more info?)
Website

Comment:

Subcribe to this comment thread
Remember my details
Google
Web CodeOdor.com

Me
Picture of me

Topics
.NET (24)
AI/Machine Learning (13)
Bioinformatics (1)
C++ (6)
cfrails (22)
ColdFusion (83)
Customer Relations (19)
DRY (18)
DSLs (13)
Future Tech (4)
Games (6)
Groovy/Grails (7)
IDEs (9)
Java (43)
JavaScript (3)
Lisp (1)
Mac OS (1)
Management (1)
Miscellany (61)
OOAD (36)
Programming (116)
Programming Quotables (7)
Rails (19)
Ruby (53)
Save Your Job (57)
scriptaGulous (4)
Software Development Process (23)
TDD (41)
TDDing xorblog (6)
Tools (4)
Web Development (5)
YAGNI (11)

Resources
Agile Manifesto & Principles
Principles Of OOD
ColdFusion
CFUnit
Ruby
Ruby on Rails
JUnit



RSS 2.0: Full Post | Short Blurb
Subscribe by email:

Delivered by FeedBurner