20080829

Do You Comment Too Much?

Commenting is obviously an important part of programming, but it is possible to take it too far. Too many comments can muddle the readability of code.

Overcommented Code

When I was a TA at Carnegie Mellon University, we always made code commenting worth 10 out of 100 points on a project. Students understood when they received no points for not commenting, but they would always complain when they were docked points for commenting too much. However, developers can take it to extremes when we do things like this:


/**
* Counts the number of times char c shows up in String str
*/
public int countChar(char c, String str) {
// intialize the count
int count = 0;

// loops until end of string
for (int i=0; i<str.length; i++) {
// if character in string at position i is equal to c
if (str.charAt(i) == c) {
// increase count
count++;
}
}

// returns the count
return count;
}

I find this to be harder to read than if the code had no comments at all:

/**
* Counts the number of times char c shows up in String str
*/
public int countChar(char c, String str) {
int count = 0;

for (int i=0; i<str.length; i++) {
if (str.charAt(i) == c) {
count++;
}
}

return count;
}

I am in no way saying that code should not be commented. Instead, it should only be commented in situations where the comments are there for a reason, instead of being a copy of the line of code below it.

How to Know When to Comment

Situations that deserve comments:
  • Complicated nested loop structure - This is the textbook case and should be clear.
  • Assumptions - If you are coding or omitting a case because of an assumption or a "guaranteed" situation found earlier in the code (even in the same function), comment that you are making this assumption
  • Strange Requirements - Sometimes you have to code something in a strange way due to strange requirements. In this case, cite the requirement (document name, section, and page) in the comments so another coder coming back to this section won't think it looks weird and try to "fix" working code
  • A hack, fix, or exception for a specific bug or request - cite the bug number or the requester's name and date requested
  • TODOs/FIXMEs - There are many situations where a portion of code is left unfinished or hacked due to time constraints. It may be a case that you do not have to deal with yet but might in the future, or it may be a quick bug fix. In these cases leave a comment with a TODO or FIXME flag so it will be more likely someone will get back to it, and so another person working in the code looking for a bug may realize that it was something not implemented in the first place.

Commenting code is important, but it's also important that it's only used in certain situations. For example, writing javadocs for getters and setters on POJOs are unnecessary. If the API user cannot figure out what getName() and setName(String name) do, then I'm not really sure a comment would help them. Use comments for a purpose.


9 comments:

Chris Benard said...

Here's my response (in code) in C# using .Net 3.5 extension method too, but also implemented as a regular static method that takes a string instance.

http://pastebin.ca/1188468

RoboJenny said...

Heh. I think my code sample was actually pretty weak. I just wanted something short though to illustrate my point wrt overcommenting.

Sadly, I have seen far more egregious examples in production code at more than one of the companies I've worked for, but the same situation where every line is commented.

Chris said...

I totally agree with the premise of your post. But... :)

Given your code snippet I would use it as an example of under-commenting. I would at the very least expect a clarification on what happens when str is null (in Java you'd throw a NullPointerException in that code). Commenting code is more than explaining the "what" (which should be pretty obvious) but also the "why", preconditions, and postconditions that someone would need to know in order to use your code correctly.

Excellent point though.

RoboJenny said...

As I stated in the post, I am in no way saying that code should not be commented. Neither code snippet were examples of the "correct" way, but rather two different examples of poor commenting. I was merely illustrating that even an example with commenting could be messier than the already incorrect example of not commenting at all.

What you stated is exactly an example I stated in my list of situations to comment: stating assumptions. I do think you explained it more eloquently though.

Thank you for you comments.

Bruko said...

I used to comment quite a bit, but then my girlfriend was, like, "I'm getting sick of your little comments", so I had to pare it down. Now I barely comment at all and, overall, I'd have to say that my relationship is better.

ton said...

Damn Jenny you're pretty damn sexy. Anywhoo this really all boils down to comments should focus on WHY not how...

Michael B said...

Don't use inline comments, I gues the handgrenate story holds (see pointers). Never pull the pin, when you think you need it. Cause when you actually need it you'll know it. (mostly follows the list)

The rest folds(in any half decent IDE) so shouldn't have to hurt anyone.

"Complicated nested loop structure - This is the textbook case and should be clear."
Given cyclomatic complexity such a case shouldn't exist. split it up into separate methods.

"For example, writing javadocs for getters and setters on POJOs are unnecessary. If the API user cannot figure out what getName() and setName(String name) do, then I'm not really sure a comment would help them. Use comments for a purpose." You just missed the nail. Now name is perhaps a bad example but in other cases you might want to comment(lacking annotations) return value (non-)null / empty collection? etc

mds said...

Hehe "TODO/FIXME" is one of my favorite comments (and probably the only one on that list I use correctly every time)

shimniok said...

Good article with good advice! Thanks for sharing that. Will definitely take it to heart.

I tend to put comments in as if I'm writing to myself in the future when I look at the code and have no clue what the heck the past version of myself was thinking. That's the whole point anyway.

I think comments need to explain what I'm trying to accomplish, why I'm trying to accomplish it, and for less obvious subroutines, how I'm accomplishing it.

I picked up a habit of using a standard comment block above subroutines / objects and at the top of files. Description, input output side effect, etc. Makes it much easier to skim thru code later.

example code for Pokey: http://homepage.mac.com/michael_shimniok/Robot/PokeySource20080409.tgz

Michael