The types of comments I've found useful are ones that explain "why". Either summarizing a function or class at a high level (why I should use this thing, why it exists), or explaining a single line iff it's highly counter-intuitive. e.g.,
"This is a Foo to replace the broken one in the Bar library, which doesn't frotz Baz correctly."
"Yes, we actually have to do this because Qux isn't in magic mode yet."
I figure a comment is worth it if it's highly likely to save someone from ripping out/changing a section just to see why it's done that way (which is sometimes a fun exercise, but mostly just reminds you of some subtle detail you forgot).
After reading "Refactoring" by Martin Fowler, I would say "comments are bugs". I still operate that way, excepting a one-line description of a function or class. In rare situations, a longer explanation of convoluted code is called for.
Yes, I am still trying to reconcile this with "Literate Programming", unsuccessfully.
"This is a Foo to replace the broken one in the Bar library, which doesn't frotz Baz correctly." "Yes, we actually have to do this because Qux isn't in magic mode yet."
I figure a comment is worth it if it's highly likely to save someone from ripping out/changing a section just to see why it's done that way (which is sometimes a fun exercise, but mostly just reminds you of some subtle detail you forgot).