. . . and one of the plenty of good reasons being producing API documentation automatically via javadoc, doxygen, etc. Having the API documentation source and code live together is a big win. It's easier to maintain the inline documentation so it doesn't go stale. I hate being forced to go read code when I just want to use an API (I'm looking at you, Dojo :-/ ).

One of the first things I'll do encountering a feral code base is run an automatic documentation generator over it, even if there are no API comments, because many will produce at least some level of documentation from pure code, including cross references, a type index, call graphs, type diagrams, etc. This can be especially helpful when the code is poorly organized, and trying to trace simple program flow in an editor means navigating a dozen modules manually. Doxygen, for instance, will produce hyperlinked program listing, so that I can use a browser in a natural fashion to navigate the code structure and program flow. The browser can maintain virtually unlimited context, whereas my brain loses track of where I am once I'm seven levels deep in function call nesting.

Some IDEs and UML tools also are capable of reverse engineering documentation from the code base. The Togethersoft tools used to be excellent at grinding through code (and may still be, but I haven't used them in years).

RE'ed documentation of feral code can reveal how well (or more frequently poorly) the code base is structured, and identify key areas for architectural or design refactoring (if that luxury is possible).

In writing my own code, I decompose until each function or method has a single purpose (f() does X, not X & Y & Z!), and therefore the API documentation suffices to document the code itself. Rarely do I write a comment inside the body of a function or method. That happens when I re-visit the code, and discover that it's operation is non-obvious. The non-obvious stuff tends to be the tricky stuff it took some time to get right, and so it doesn't get mucked around with, and such internal comments rarely go stale.

I wait until re-visiting the code because authorial bias (my code effectively become's someone else's after several weeks, sometimes faster :-) ) obscures what is and is not obvious. I used to over-comment from a tendency to perform a mini-brain dump in comments -- but the knowledge required to WRITE the code (this is what I was thinking at the moment) is no reliable indicator of that required to READ the code (this is what _you_ need to know).

(I've theorized that having someone else comment the code from the start, just like having an unbiased tester, could make for better comments -- wherein the commenter is also necessarily a code reviewer as well. I've never gotten any of the places I've worked to agree to 'cross-commenting' as a standard practise, but most love worthless, perfunctory desk-checks prior to check in.)

To avoid comment churn, and because I refactor aggressively when creating brand new code, writing API comments is the LAST step in coding.

Finally, I developed a habit of writing comments exclusively in point form, because context switching from programming constructs to proper English grammar broke my flow. The point form comments feel like a miniature brain dump, whereas otherwise I'd pause to think about how to put the information into a proper sentence, and then make nice paragraphs, and suddenly I'd be channeling me from 7th grade compsition class. It's also easier to scan and digest comments as point form notes.

That's what I do, and I leave it at that, because telling someone else how to code is like telling them how to raise their children.

tl;dr version

- at least write API comments, pls

- doc generators (and other tools) sometimes are a great way to RE docs for feral code

- write comments in point form

- write API comments as the FINAL step in coding

- try to remove authorial bias from comment writing