There is a common tendency, as we crank out code, to think that we’ll come back later and write some really good comments — comments that future reviewers will view with admiration for their clarity, completeness, and humor. But if we’re honest we have to admit: Later never comes. We never go back and write those great comments. Often we don’t write any comments at all other than some placeholder we might dash off at the time.
Which is why Rule #4: Comment As You Go!
There is a practice — and I think it’s a good one — of writing a detailed and descriptive function, method, or class, comment first, before writing any code. Essentially, you describe what you’re about to code.
For one thing, explicitly describing a design helps clarify your mind regarding the design. In some cases, a detailed description makes the coding trivial. In others, the description may make you aware of lurking problems you hadn’t noticed.
There is an ethic that creating software should involve 90% design and 10% coding. There are design methods that evolve designs through refinement stages and ultimately into the code. Literate Programming seeks to turn high-level descriptions of software into code. Fast Prototyping seeks to turn increasingly complex models into refined products.
[The first programming job I applied for involved converting flow charts created by software designers into COBOL code. This was a low-level entry position — the coding was viewed as trivial. The real work was done by the guys (and it was all guys, of course) who made the flowcharts.]
So writing a detailed comment describing the function, method, or class (or a lot of things; let’s just say “object” from here on), focuses and clarifies the mind, plus it’s the right thing to do for good designers. It also ensures that a good comment exists!
It’s a bit like how, in Test Driven Design, you’re supposed to create the test(s) first. It guarantees the tests do get created. Write the comments first for the same reason.
[For the record: I think TDD is a good thing sprinkled lightly throughout a project. I think it’s possible to get carried away — I’ve found myself spending more time creating tests than code. (OTOH, I love the robustness this creates.) The thing is, you can never create a complete test suite — complete coverage is often impossible. So you can over-rely on TDD. I’m more of a believer in system-testing under real conditions. FWIW]
It’s easy to get caught up in the heat of coding. Code, code, code! There is a mental switch required to write descriptive comments. It’s possible that switching gears like that is actually a good thing. There can be a highway hypnosis locked-in thing that ends up error-prone due to unnoticed fatigue and target fixation. Taking a breath to describe your work can improve your rhythm and endurance.
The counter-argument — and it is a valid one — is that early comments risk being outdated by changes to the code. The comments have to be updated along with the code. This creates one of the most prevalent instances of one of software design’s greatest challenges: synchronization.
Any time two things must be kept in sync — database field names and the use of those names in code, for example — there is the burden of having to update both if either changes.
There is no more common example of this than code and comments. The deadly part is that the comments can be wrong without actually impacting the code. (The code is always “right” — or, at least it always wins.) And yet the comments are the part programmers read first.
It’s when you read a comment and go, “Huh?!” that you might look closely at the code to see what it actually does. When cases like this are especially bad, it’s easy to wish there were no misleading comments in the first place.
There is also an argument about “self-documenting” code, and this argument also has a point. To the extent that the code itself can clearly describe what it’s doing, comments are superfluous. But this requires that the code be clear (Rule #1!). Key to this is that variable names be descriptive and obvious. It also usually implies short code bits with each bit doing a single obvious task.
Even code like this deserves a high-level descriptive comment to introduce it, to explain its purpose in life. (OTOH, a well-chosen object name can go a long way in describing what an object is for.)
But to be blunt, well-written self-documenting code is an advanced technique that takes most programmers years to achieve. Many never do; some programmers just never rise above Journeyman level (and some never above Novice). Good coding is partially a talent; you either have it or you don’t.
So obey Rule #4: Comment As You Go!
And consider commenting first, coding second. It’s a pretty good habit to develop.