Not mentioned in this article is the effect that dynamic typing vs. static typing has on how you comment. It is common practice in Clojure, for example, to heavily document every function, because it is a dynamic language and there are no other obvious ways to indicate the types of arguments or the function's return value (though that is gradually changing in the language, but not entirely). This practice is so encouraged and standard in Clojure that all functions can be defined with language-standard documentation strings that become a part of the function definition, which can then be looked up at the REPL.
Some statically typed languages don't suffer from this particular problem of making types clear, so you will see comments less, and reserved more for cases where logic is hard to parse conceptually. But some static languages have a similar problem due to type inference, which causes commenting in the same fashion as a dynamic language.
I am of the school of thought that except for making types clear, the best way to comment your code is to make the code as clear as possible so that it is obvious without extra explanation. Often, you can refactor a clumsy or confusing piece of code in a way to make its intent clear.
But sometimes you cannot, and that's where comments come in.