Search This Blog

Loading...

Tuesday, March 18, 2008

The One Single Tip to Comment Your Code

Well, there is an article on 13 Tips to Comment Your Code. A well written piece of article, indeed. In the article there are a lot of good advices on how to comment your code so that other people can get the most out of your program.

Here I would like to offer the One Single Tip on code comments. This tip is the aggregation of my software development experience, so hopefully it could be useful to others.

Ready? Here it is the One Single Tip:

Let your code document itself!


Yup, the only true documentation, my friend, is your source code and nothing else. XML documentation, or any other form of documentation, although sounds great in theory, but nevertheless in practice they don't work. Why? Because they are simply not a part of the executables.

You see, we developers are very busy, and we abhor paperwork. Documentation sounds so second-class that if you assign a junior developer to write XML documentation for his senior, he will surely give you a blank stare. Not just that, code changes, everyday. When bugs come in, you need to modify your code to get it removed. When requests come in, you need to upgrade your program to implement the new features. When your code is broken, either your program won't compile or your tests won't pass.

But when bugs come in, you don't need to modify the comments; changing the comments is useless anyway, it won't get you an inch closer to your solution. When there are new feature requests, you can still left the comments intact with no effect on the implementation whatsoever. And when your comments are broken, or outdated, or are simply, downright wrong, your program can still run happily and your tests can still pass.

This is why comments are, hmm--I hate to say this because it is going to alienate a lot of documentation tools providers-- redundant. Instead of relying on comments to convey your intention, why not let your code--be it the production code or test code-- shows what your module does exactly?

Instead of writing a lot of comments to explain the subtle behaviors of your program, why not restructure your logics so that they are self-evident? Instead of documenting what a method is doing, why not choose a clear name for that method? Instead of tagging your code to indicate unfinished work, why not just throw an NotImplementedException()? Instead of worrying whether your comments sound polite enough to your boss, your colleagues or anyone reading the code, why not just stop worrying by not writing them at all?

The clearer your code is, the easier it is to maintain it, to extend it, to work on it on future editions. The less ordorous is your code, the less need there is to comment it. The more the comments, the higher the maintanence cost.

There is one qualification to my points, however. I am writing this assuming that you are not developing your next generation quantitative model that allows you to short and long derivatives with 100% success rate.

If you have a brilliant algorithm, or you have come up with a superb mathematical model that describes the Secret of Universe but no one has heard of it yet, then of course you need to document it. But this type of documentation is very far from the concepts we associated with our source code documentation.

To properly document your algorithm, you should
  1. Write it in Microsoft Word
  2. Type in all the mathematical symbols
  3. Polish it into an accepted format
  4. Send it for peer review and for publication purpose
  5. Refer to the paper in your XML documentation
So there it is, the One Single Tip to comment your code. Hopefully by reducing the number of tips from 13 to 1 my fellow developers would have a better time in writing better comments!

Follow up Post: Comment on Why? Why?

26 comments:

DevTopics said...

I agree! I am a big believer in writing self-explanatory code. However, that only explains WHAT the code is doing, but it rarely explains WHY we are doing it. In cases where a WHY explanation is needed, comments are still quite useful.

ohxten said...

I agree as well. It's the only way to do it. devtopics hit the nail on the head as well.

Also, sometimes it depends on the language. If you're using assembly, the more comments, the better.

Mark Wilden said...

I put it slightly differently: 1) Only write comments for code that's hard to understand. 2) Try not to write code that's hard to understand.

Another point: Identifiers are not executable! Code can have out-of-date identifiers just as it can have out-of-date comments. You can't really know what the code does without reading every line of every method - and that's clearly not possible. Don't assume that because you understand the code in a method, you understand what it's really doing.

As for explaining "why," that should not be necessary, as much as possible. The "why" should be obvious - if it's not obvious, comment it. But see the first paragraph above.

That said, I absolutely agree with the general thrust of the article.

///ark

Heiko Hatzfeld said...

I think the Article is exactly right.

You think need to comment a small piece of code? Refactor it into a helper method with a resonable name. I dont mind long method names. I dont type then by hand anyway... And its much easier to understand a call to a method, then some comments.

How about a method like

private string GetErrorTextFromXml(XMLDocument response){....}

You dont see the code, but you know hat i want to do. And if the customer wants documentation for the method... Its only one ctrl+D away if you use ghostdoc (Great tool for generating XML Documentation)

Robert Ludlum said...

Oh dear.

You either don't work in a real development house or you are some kind of genius or sociopath.

Yes, code should be self documenting. However, why would you want to require a developer to troll through line after line of code in order to find an error, and for them to have to understand everything that is going on.

Compare this to a reference book. If there were no headings, you would need to skim through the entire book to find the bit you need. Same with the code. Add some simple "paragraph" comments and you make life easier for everyone.

Comments that get out of date when the code changes are bad comments. Comments should describe the purpose of the code and not the workings.

Heiko, your example of GetErrorTextFromXml is almost a case in point. A comment that says "This gets the error text from the XML" would be a bad comment. However, can you tell from your code WHY you are doing this?

Final note. If you think that comments take too long to type, take a typing course. I am always suspicious about employing developers who cannot type fast.

Soon Hui said...

Robert, thank you for your comments.

Yes, code should be self documenting. However, why would you want to require a developer to troll through line after line of code in order to find an error, and for them to have to understand everything that is going on.

Compare this to a reference book. If there were no headings, you would need to skim through the entire book to find the bit you need. Same with the code. Add some simple "paragraph" comments and you make life easier for everyone.

I think you are stretching this comparison a bit too far. Headings in books and comments in code are not good analogies. Headings are always updated, useful and helpful; whereas comments are always outdated, useless and confusing.

A better analogy is to compare the comments to headings that never get changed even after a book undergoes a few drafts. That's a more appropriate analogy.

Comments that get out of date when the code changes are bad comments.
If you've ever worked on commercial software projects, you would realize that comments always get out of date. So by your definition the comments are always bad.

Comments should describe the purpose of the code and not the workings.
I'm going to write a post to address this point. Stay tuned.

Robert Ludlum said...

Soon Hui...

I do work on commercial developments.

You are partially right, even good comments can get out of date. However, in a commercial environment one would expect to conduct code reviews that will highlight these problems.

In the end it is a matter of professionalism. If you are changing the PURPOSE of a piece of code, the comment will need to be updated also. In reality, most maintenance changes to production code at this level of detail tend to be bug fixes.

Sloppy coders who bang out a change without considering the impact upon the comment that is two lines of code away and probably highlighted in a different colour are probably the same sloppy coders who bang out a change without considering the impact upon the rest of the system too.

I don't want those coders working in my business.

Robert Ludlum said...

...I should probably add that "Self-documenting" code that is buggy can sometimes document the wrong thing. Whereas a comment describing the code's purpose (that has been maintained if the purpose changed) will not.

James Curran said...

ah.. Robert just posted exactly what I was going to.

I'm a big fan of self-documenting code -- except that it can only document what the code DOES, not what it is SUPPOSED to do. It becomes impossible to tell what is the purpose of the method apart from what is just an unintended side-effect apart from what is just a plain bug.

Mark Wilden said...

Yeah, I see this kind of code all the time:

// This code is supposed to get text from an XML document
string GetTextFromXMLDocument(XMLDocument)

:)

The place to find out what code is supposed to do is the tests.

///ark

Seth Petry-Johnson said...


"Instead of relying on comments to convey your intention, why not let your code--be it the production code or test code-- shows what your module does exactly?"


This demonstrates you just don't get it. What my module DOES and what I INTENDED it to do can be very different, e.g. when there's a bug in the code. Comments help future programmers identify that gap and close it appropriately.

SeanJA said...

print"@{[unpack'(b8)*','\x90\x9f\x88@\xb9.\xc7\xdax82j\xa3\xc6j\x11\x3']}"

What does that do then?

SeanJA said...

Apparently it went off the line (I figured that it would be smart enough to line wrap...apparently not) so, here it is (it is all supposed to be one line though)

print"@{[unpack'(b8)*','\x90\x9f\x88@
\xb9.\xc7\xdax82j\xa3\xc6j\x11\x3']}"

Mark Wilden said...

>print"@{[unpack'(b8)*','\x90\x9f\x88@\xb9.\xc7\xd>ax82j\xa3\xc6j\x11\x3']}"

>What does that do then?

What's the name of that function?

///ark

Anonymous said...

This demonstrates you just don't get it. What my module DOES and what I INTENDED it to do can be very different, e.g. when there's a bug in the code. Comments help future programmers identify that gap and close it appropriately.

A comprehensive unit test suite is a better way to describe what the code is supposed to do.

Soon Hui said...

Comment on Why? Why?

Anonymous said...

Fortunately, your not part of a development team in my organization!

Won't comment your code to help make it more maintainable? Then it's time to dust off your CV and head for a bucket shop that only writes "new" code.

Anonymous said...

Every comment is a potential liability.

Comments are dangerous, as there is no compiler or unit test that will identify code that is improperly documented or comments which are ill-maintained.

Improper comments such as these are ticking timebombs awaiting for some developer to be lead astray
by them. The implications of this are greater costs, introduction of new bugs, and the liability generated from the new bugs (lost data, mis-calculated interest, delayed inventory, etc.).

The three types of comments that can provide value to development and maintenance are :

(in order of least liability)

- Comments providing historical insight explaining key implementation details (history rarely changes!)

- Comments that provide architectural overview (changes with major system changes only by architects)

- Comments which describe non-obvious implementation-specific details (subject to changes by bug fixes and feature additions by multiple mixed-level developers)


Comments that describe the things that change the least can provide the most value as their risk of being out-of-date is lowest.


Comments that describe the architecture of a system provide the most value because they should have the least overhead and provide the greatest insight.

A well thought out architecture should have few architectural changes, so most comments made of this type should rarely change -- thus having much less upkeep. Additionally, some of these comments can be generated when modeling the architecture with CASE tools.

Comments that describe the implementation of an architectural component should be focused on clarifying the non-obvious. The goal being "make your code obvious", thus requiring fewer comments.

Implementation-specific comments require the overhead of maintenance, whereas architectural comments should only change when there are major system changes such as an architectural redesign.

Proper source control can help mitigate the necessity of maintaining method-level implementatation change history comments in the code.

Source code + comments should reflect the current state of the code, and only include "history" information if it provides insight into a decision, not maintenance history. "Insight into a decision" is for situations where doing something the obvious (perhaps former) way will no longer work.

// can no longer use shared library because it causes a divide by zero exception
// must now calculate this manually as of version 2.0.6

A comment such as this provides background information into this decision + prevents future developers from deciding to "tidy up" the code without considering the ramifications.

Heiko Hatzfeld said...

Yeah, I see this kind of code all the time:

// This code is supposed to get text from an XML document
string GetTextFromXMLDocument(XMLDocument)

:)

The place to find out what code is supposed to do is the tests.

///ark


Exactly...

Tests serve a much better source for informations then comments. Noone is forced to keep comments in sync with the code... But if you fail to keep a test in sync with your code, then you have a red bar, that needs to get fixed. Even those who said comments are importent allways feld they had to add "(If they are maintained)" etc... But how can you tell that they are maintained?

I still say that most comments are useless. The code should be small and very easy to understand. Comments are only needed on some very odd situations, which dont make sense without knowing why you do it...

Example:

SubmitCommand(xmlConfiguration);
//HACK:Error in external interface. Need to do it twice so it "sticks". Ticket opend with Vendor XYZ
SubmitCommand(xmlConfiguration);

SeanJA said...

print"@{[unpack'(b8)*','\x90\x9f\x88@\xb9.\xc7\xd>ax82j\xa3\xc6j\x11\x3']}"

>What does that do then?

What's the name of that function?


It doesn't have one.

Mark Wilden said...

> It doesn't have one.

Then there's your problem.

Don't expect comments to make up for poor code organization. As Tim Ottinger says, comments are often an apology for bad code.

///ark

Mick Bennet said...

One Tip for Commenting? Don't be Lazy

http://mickbennet.blogspot.com/2008/03/one-tip-for-commenting-dont-be-lazy.html

Anonymous said...

only douchebags use ms word for math. Use LaTeX: it is prettier, easier, and better.

TimOttinger said...

My ONE TIP TO COMMENT YOUR CODE is this:

Whatever a program *can* express, it must express it in code. Comments are for information that cannot be expressed in code.


If you think you can't express what/why/how/when in your code, you're probably wrong. Comments are not for history (version control is). Comments are for metafacts not programming facts.

Anonymous said...

I really don't care anymore about who is right or wrong when it comes to discussions such as this one, I am just SOOOOOOOOO sick of the damn fanatics who preach "This is the way I do it, so this is the only way to do it", whatever "it" is.

You people really need to get over yourselves and just develop the software you say you are developing.

Anonymous said...

Only a year late, but hey...

In an ideal world all code would be self-explanitory and all intent would be speficied in test cases. The very occasional meta-information would take the form of commented haiku poems. All programmers would have the skill and discipline to do it all and not to stray.

Where I live many programmers have a hard enough time coming up with meaningful names. But they can all grasp the concept of comments and occasionally you find one that really helps. That's nice.