Friday, September 08, 2006
I keep hearing complaints that a piece of code is hard to read and understand because it is not well commented.
I'd like to say something about that. The source code may be unreadable, but it's not because of lack of comments, it's because the source code is unreadable.
 
I'd just like to clarify what I'm talking about here. The kind of comments I refer to is the kind that sits inside the souce code between /* */ tags, or behind // or -- or ' or REM or whatever delimiter is used to mark source code comments. Comments that the compiler ignores and is just there for humans to read. (I do not refer to xml documentation).
 
If the source code is unreadable it's because it has been written in a messy fashion with weird or nonsense variable and function names. The factoring is all wrong so the logic is all over the place, either in a huge block of massive spaghetti, or split into methods that do half of this and half of that, and dependent on code that is all over some other place.
 
It might help some tiny bit to throw in some comments into this mess. But most of the time, the only really helpful thing to do is to refactor. Code that is properly written is virtually self-documenting. The names of methods say what they do, they don't do more than they say, they sit in a class that has a specific purpose, and is named thereafter. You can read the code line by line and know what is going on. In this kind of code there is no need for comments.
 
Well, of course, some comments can be good. But only when they provide some additional information other than just explaining what the code is doing. The code should state just fine what it is doing. What is needed of comments is things like noting when you are doing something that could seem weird, but there is a good reason why its done this way, like working around some bug, or special case, or relying on some invisible side-effect.
UPDATE MenuItems SET ParentId = ParentId  -- Make the trigger on ParentId recalculate FullPath
Or stating intent where it's not already clear. Like when you intend to leave an empty catch clause for good reason, you could put an "// ignore any exceptions" inside that catch. This way it's clear that you didn't just forget to log it.
 
Commenting every few lines of code only stating exactly what it does, only in English rather than code, is just useless.
// Ok, so if the given username is null we'll just return null 
if (username == null)
    return null;
Your comments aren't verified by the compiler, so they may very well be wrong after someone has gone and fixed the code but forgot to update the comments.
// Ok, so if the given username is null we'll just return null 
if (username == null)
    throw new ArgumentNullException("username");
Also, lots of comments look messy too, and use up a lot of verical space, making it harder to follow the flow of the code.
 
There are many tricks to writing readable code. Naming, class responsibilities, proper abstraction and encapsulation, levels of nesting and guard clauses, error handling, indenting, small-scope methods. It's a skill, an art, and subject to great disagreement and controversy. A lot can be said about how to make clean code, but comments don't make code cleaner, they just attempt to guide you through the mess.