There is a faction in programming that views any comment as a failure by the the programmer to express himself clearly enough via the code alone. The anti-comment bias has a lot of merit since there does seem to be a sizeable number of coders who make no attempt to use good variable or methods names and attempt to compensate for this shortcoming with a liberal use of comments.
I was in the former faction for a short while till I realized the absolute lunacy of it and now happily employ comments on a daily basis.
One of the most applicable skills I learned when I took martial arts as a kid was how to spot telegraphing — slight movements by your opponent that signal his intentions. After being taught what to look for — shifts in balance, changes in breathing, widening eyes — it amazed me how easy it was to anticipate and attack and how insanely difficult it was to prevent your own body from sending out the same signals and telegraphing your intentions.
While you work hard in martial arts to suppress telegraphing, I’ve learned that the opposite is true for almost any team endeavor. On a sailboat — where long periods of idleness are punctuated with a few seconds of furious activity — telegraphing is vital to the smooth functioning of the boat. One-word commands and status updates are shouted back and forth in the few furious seconds of a mark rounding or jibe but, unless you know the context of each shout, it’s a chaotic mess.
I think telegraphing is equally important in writing maintainable code. In everything you write, your objective is to communicate your intentions to the next programmer (or, more typically, yourself six months down the road).
Good variable and method naming are vital in this regard and there is absolutely no excuse for cryptic variable names or thousand-line methods. But when you have done your best to telegraph your intentions via the code itself, and still feel that some ambiguity remains, don’t hesitate to add comments to your code. You will thank yourself six months down the road.