I don't believe "self-documenting code" is the be-all end-all. Just because everything is easily readable and makes total sense to you doesn't mean it will be as readable to anybody else that's poking around, or even to yourself a few weeks down the line when you've taken a break. Comments are a tool, just like an IDE or a compiler.
Self-documenting code isn't the be-all-end-all, you're right about that.
But with Common Lisp/Haskell/any language with a decent Syntax I don't only have code I can actually read comfortably (as opposed to something like what Telgin just posted) but often there are other features which help mitigate the necessity of comments.
Haskell has its types, which function effectively as a part of the specification that can be programmatically checked, so they are never incorrect or out-of-date.
Common Lisp and Haskell both have a REPL (although the one for Haskell is quite incomplete), so if you don't understand what a certain part of the code does, you can just check immediately. Note that this doesn't prevent compilation.
Common Lisp also has macros like TRACE, which allow, well, tracing and untracing of functions with one call, like this (I think I've got the format wrong, but that's hardly important):
> (trace foo)
FOO
> (foo 3)
: (FOO 3)
: (FOO 2)
: (FOO 1)
-> 0
-> 1
-> 2
Common Lisp also has very sophisticated error handling facilities (not only throw and catch but also so-called "restarts", which provide a way of jumping back into the context where the error happened, instead of being stuck with unwound stack of where the catch happened) and documentation strings (which are basically comments, only that they're associated with the function/variable being defined) which can be accessed without looking into the code, so you can check what a certain function does if you know only its name, without needing to search for where it is defined.
Then there are type annotations and probably many more features I forgot. Not to speak how it might be a better practice to write a macro encapsulating an unusual idea so it becomes easily readable than to comment it. The macro shouldn't be documented with a comment, but a documentation string and how it works can be checked with MACROEXPAND in the REPL.
The remaining cases where comments are actually useful are sparse.
One way to prevent comment rot would be to tie comments to specific code lines. I don't know, maybe a program that goes over a source file, making checksums for code and accompanying comments (how would you detect which part of the code a given comment was for? In Common Lisp you'd count leading ';'s and associate with the appropriate source subtree) and then you can check afterwards whether the checksum of the code changes without the comment checksum changing, too.