When I'm talking to beginning programmers about code comments, I give them a simple rule: don't use them. Instead, rework your code until a comment would be superfluous. Great method names abolish the need for 99% of the comments that beginning programmers create.
I'm a firm believer in the value of simple rules for beginners. They ignore subtleties but help the newbie do the right thing the majority of the time.
For the experienced programmer, condemning all comments is too simplistic. Occasionally, writing a comment is the best choice.
When I use comments
When I have to do something really weird.
If a library has a bizarre bug that requires a workaround, I will leave an explanatory comment as close to my hack as possible. There are many similar scenarios, but their common thread is they will likely surprise a project's future maintainers.
As class-level documentation.
I very much like documenting classes with a short, high-level description of their purpose. This is almost always a single line just above the class declaration. If the description is both short and high-level, it is unlikely to get out of sync with the code (a comment's greatest sin).
As TODOs in my own branches.
I will sometimes insert a TODO comment in my local branch. These notes are for things I want to do before submitting my code for review. A reviewer will never see them, and I never merge them into shared branches.
Other half-formed thoughts on comments
When I am forced to leave a comment, I use proper capitalization and punctuation. If I have to bring another comment into the world it might as well look nice.
One idea I've been toying with is writing method-level documentation comments. These comments precede a method and document its parameters, side effects (boo), and return value. It also often includes examples.
When I'm writing Rails applications, I never document my methods this way. However, when I used to write Common Lisp, I got a lot of value out of creating short docstrings for every function. Additionally, I very much prefer using libraries with good method-level documentation (usually this translates directly to "Not much prose, but tons of examples").
Given that method-level comments are so helpful in these circumstances, I wonder if my code would be better if I included them. I think it's worth an experiment at the very least. If you've had lots of experience writing and reading method-level comments, please chime in on the...ahem...comments.