No one even reads those documents. The client claims they are to assist future developers - internally or another vendor - but would you trust a Word document or a .cpp file when everything is on fire and you need to figure out a system's behavior? Same thing applies for code comments.
There is one source of truth in software, the code. You can pile on the design documents, wikis, and architecture diagrams but at the end of the day, what is coded is what gets executed. Make the code easy to understand and reason about. And then, if you really want to be nice to future developers, throw in a single page overview of the codebase (README) that gives someone an entry point.
Edit: I will just add the caveat to preempt the inevitable - this does not apply to public facing documentation of an API/framework/library etc.
There's a bigger philosophical problem here. If your development cycle is code -> comment -> code -> comment ... (where you write code and then comment), then your criticism is fair. But the right way is to comment first. When you describe what you want in words, then you or anyone else can go back and evaluate if the code matches the words.
(In my experience, 90% of bugs stem from developers thinking one thing and implementing something different, and these could be avoided if you had a normative document)
It's like writing a paper: you outline, sketch out what you want to say, and then actually start crafting sentences. The outline should guide your paper, and if there's a problem you first update the outline.
And the test can actually be executed.
I used to do the "sketch it out" a lot more, but I think Test-First is a better approach.
I agree with this statement wholeheartedly. Documentation starts with readable code. Comments can go out of date and, worse, lie to you.
I wish people would stop taking these purist approaches. There is an obvious middle ground to this - document the non-obvious and your public facing APIs.
Having a comment to clarify intent is a saving grace when code looks correct but is doing the wrong thing. At least when a comment is conflicting with the code you know at once that you need to start asking questions...
> Comments - like documentation - are a liability.
Tests, too. But you wouldn't advocate not having tests, right?A well-maintained suite of automated tests provide an enormous benefit. A brittle set of Selenium scripts costs a project more than paying a Tester to manually run scenarios.
Yet comments can (and do) go way out of date.
Tl;dr not equivalent.
Let's assume good comments--not useless, lying, or broken ones. I won't contest that bad comments are at least as bad as useless, as you doubt would not contest that bad code is at least as bad as useless.
When I read a comment, I parse it directly. When I read code, no matter how neat it is, I often trigger a twitch of "How would I rewrite this?", which itself gets in the way of understanding.
The more code there is, the harder it is going to be to digest at first glance, and if your codebase could be adequately described by a single page of text I would wonder why I need to work on it instead of rewriting it entirely.
Hint: if you only have one page of docs, and especially if you have no test suite, I cannot work on the code in a meaningful way safely.
If you don't value safety, if you don't value engineering, then by all means omit comments. It's just a crutch for people who can't see the code man.
I might also point out that that same philosophy implies that we should just stick with assembly. Especially if you use any language with dynamic types/duck typing (Ruby, Javascript, etc.) seeing "at a glance" what exactly is the proper form of data to pass into and out of function can be hard. Documentation here helps.
EDIT:
Note also that commenting in libraries, or in mathematical or geometric routines, can be really helpful. The code doesn't lie, sure, but if you aren't experienced/schooled/clever enough to recognize what is going on it won't help you.
A great example of this is the fast inverse square root hack:
http://en.wikipedia.org/wiki/Fast_inverse_square_root
This has great examples of both inscrutable (but honest and short!) code, and shitty commenting.
On the other hand arcane business logic needs to be documented because there is no way to recreate that from a mental model.
Comments don't provide safety - tests do. Comments are not good engineering - well designed code that is easy to reason about and follow is.
Proof > Tests == Documentation > Correct Comments > Nothing > Incorrect Comments
None of these things are mutually exclusive, and all non-trivial code should ship with a combination (obviously excluding "incorrect comments"). I think inline comments should be relatively unneeded, and should only describe why you did something in an unusual or non-intuitive way. Otherwise, your code should require few comments, because what it does should be obvious.
Regardless, you sure as hell better document and/or test your interfaces. The nice thing about tests is that they can automatically be verified for correctness; documentation and comments cannot.
Also this should go without saying but I still see comments like this:
// loop over the collection
for (var foo in bar) {
...
}
which are not helpful and just clutter the code.Granted, this won't work in all situations. If you can't trust your colleagues to keep the comments updated (and if you don't review commits), then this is going to cause problems - however if you're writing for yourself or with a small group of people you trust, I strongly recommend giving it a go.
In general, most of Postgres code.
Also, all the long descriptions before function calls are mostly redundant. If i want to know what a function does I can go there and look, but it really should have a sufficiently descriptive name that after the first time I don't need to check again most of the time. Unless something non obvious is going on.
/* Do we have any named arguments? */
...
/* If so, we must apply reorder_function_arguments */
if (has_named_args)
{
args = reorder_function_arguments(args, func_tuple);I put this tool together on a whim (although the github rendering is somewhat strange because I took liberties with the fenced code blocks): https://github.com/niggler/voc
Even better: after writing then program, run it and save the output and throw away the source code, yeah?
// $set $foo to $bar
$foo == $bar;
// print out value of $foo
echo $foo;
// is $bar the same as $foo? if so, return true, otherwise return false
if ( $bar === $foo ) { // check if the same
return true; // great, it's true!
} else { // here we check if it isn't true
return false; // nope, not true, let's return false
}
I have nothing against comments where something needs to be documented, but not everything needs comments as most code is essentially self-documenting.Edited for clarity.
For the remaining cases it's more important to make sure that you're documenting the "why" of something in the code. If you find yourself often in the situation where making changes to the code requires modifying the comments to keep them up to date that's a big sign that you aren't writing comments appropriately.
There is something to be said for the spacing that comments allow.
// It was hard coding it
// so it should be hard reading it1) When I'm not all that familiar with the language. This allows me to grok the purpose and actions of code quicker.
2) When the action being performed contains more lines than fit in the screen. Knowing a bit more context going in can make what follows more clear.
For 1, it's a matter of who you intend to read/modify the code after you. For 2, that's probably more a case for splitting that code into multiple functions.
From that, I think comments are best used by poor and great programmers, but the middle of the road may not get much benefit out of them. If you don't know how to split your complex bits of code into multiple chunks, or if you expect most people coming after you to now be as experienced as you, comment.
Also, it's obvious that outdated comments are terrible. It is my expectation that if comments are going to be in the code at all, they should be maintained just like the rest of the code.
It makes it so much easier to get introduced to a code base, and comments like that seldomly needs to be updated.
I usually pretend I can't document my code while developing. I'll sure add some anyway.
This doesn't apply to public APIs. There, you of course need to be more explicit.