Comments and self-documentation are the two sides of the code clarity coin.
Code comments are one of the holy wars of programming--everyone has a strongly held view and debates it vigorously. I basically agree with the views in these articles:
- Why You Shouldn't Comment (or Document) Code - Visual Studio Magazine
- Comments - Source Making
- Code comments: A quick guide on when (and when not) to use them - Pluralsight
That is, comments are a liability, so for the most part write them as little as possible, and update them when you update the code. Make your code as clear as you can (see the self-documentation section), and comment only to communicate what the code can't on its own, such as its purpose and the reasoning behind your choices in implementing it. If nothing else, comments can be a good indication of places that need refactoring.
I don't think it's necessary to stick to one procedure for commenting, but generally when I've commented more, it's because I've paused after a chunk of coding time, such as when I've finished a function. I code in paragraphs, sets of related lines separated by a blank line. In the commenting phase I reread the code I've just written and try to summarize or justify each paragraph, if needed. Stepping back from the code to state things in English sometimes leads to improvements in the code--refactoring or bug fixes.
Here are some in-depth discussions on making code self-documenting:
- Self Documenting Code - WikiWikiWeb
- System Metaphor - WikiWikiWeb
- Hunting for great names in programming - Signal v. Noise
Every solution has its own problems. Self-documentation can go wrong too, and in some of the same ways comments can. For example, your function name doesn't have to have anything to do with its contents. Here are a bunch of tricks for wrecking your code's clarity:
On the problem that documentation isn't executable, behavior-driven development might give us a partial solution. See the links in the test-driven development section above.