(I don't write code for a living these days btw, only for myself. It's much more fun, and I get to not care anymore whether other people think I'm wrong about things like these).
(I don't write code for a living these days btw, only for myself. It's much more fun, and I get to not care anymore whether other people think I'm wrong about things like these).
> I never actually trust that documentation to be accurate or up-to-date. I expect it to be misleading and time-wasting, and so I only trust the code itself.
Two things here:
1) I don't implicitly trust comments. Obviously, the code is the definitive source of reference, and where the comment differs from the code, it only means that something interesting happened. But...
2) I believe in commenting "why" or "who", and less often, "what" (and rarely "how"). My experience is that "why" comments age well -- even if the code drifts, the intent of a method or class changes infrequently.
For example:
# I (timr) wrote this method because I needed a way to
# invert the index for {situation}, and {method a} and
# {method b} didn't work because {reason}.
is a better, more evergreen comment than: # this method inverts the index for {situation}.
which is far better than: ##
# inverts index.
# @args foo, bar, baz
#
Unfortunately, nearly all doc generation software encourages the latter, and so many comments are pretty darned useless. The first example is great because even if {method a} and {method b} and {reason} fail to be true in the future, some other programmer can come along and read it and say "ok, I understand why this was written this way, and the preconditions motivating it are no longer valid. maybe I can refactor."This is hugely valuable.
I actually completely agree with your ordering of least-useful to most-useful comments. I still tend to view these most-useful comments as just kind of interesting historical tidbits, rather than something that really helps me do my job, but at least we agree on the order :)
Nah...I'm joking about you mocking me. We definitely had this conversation a few times, though.
I appreciate having this kind of information available, but it often gets too verbose for my taste to keep as inline comment. For this, I typically push this kind of documentation to the commit messages. This however requires very disciplined use of git: you need to "massage" your commits so each of them is a self-contained change, and OFC avoid squashing during PR merges. Then, a git blame + git show will bring up the relevant information.
There are comments that are categorically always bad. These are the "this code does X" kind of comments. Those go out of date really quickly in a shared code base. They don't even make sense for myself on a project I'm doing myself. The code should read like the comment would. Almost like prose. If it doesn't, I haven't made the code good enough yet. We no longer live in a world where the code needs to only be machine readable and unreadable to most mortals. We have the luxury of being able to use good abstractions and extract functions without worrying about code running slow because of too many indirections, stacks that are too big etc. We can optimize for direct code readability!
Then there are the "why" comments. Those can be invaluable. If I assume I have the kind of good code I can just read as to the "what is this doing", I can sparingly add information to things that might seem unusual or weird or inexplainable.
Same with tests mentioned in some sibling posts. Tests should be written in a self documenting way. I like to name my tests after what they're testing. Like "should behave in X manner when doing Y to Z" from a user's point of view, not on a technical level. User not necessarily meaning end user, say if you're testing an API or library function. Different language make this easier or harder but I do it in all of them. Armed with that documentation of what my tests pre-requisites are and what the expected outcome is, I can write the actual test. I should be able to deduce the expectations of the test from the test's "name", thus double checking that I am testing the correct thing. Many tests I find in shared code bases are utterly unreadable, have way too many expectations and side effects and test too many things at once. With the above technique there's usually only one or very few expectations. If I parsed out the test names from all my tests and just gave them to you as a document, it should almost read like a documentation of all of the expected behaviors of my piece of software.
but I never actually trust that documentation to be accurate or up-to-date
This is like saying food is bad, because it can spoil. Sure, but we have ways of preventing that and figuring out when it happens.A simple git blame or history (or the equivalent) should quickly answer a number of questions. Is the code significantly newer than the comment? Who can I ask for verification? etc.
It's not perfect, but significantly better than the alternative.
Similarly, presumably code changes are approved by reviewers, who should be preventing the merging of code that invalidates its own inline documentation without an update to the comments.