My extended thoughts on this (in addition to comments posted above):
Not a fan of literate programming then?
http://www.literateprogramming.com
Personally, I think Knuth is on to something very valuable.
Like you, I really appreciate self-documenting code, but there are times when comments are absolutely essential for the next developer.
Your post can too easily be misconstrued; and, if there is one extreme that I have come across all too often it is the absence of comments.
Jeff, have you ever worked as a maintenance developer on a large application?
I prefer to start with comments and fill in the code. This leads to good comments and good code. Once the code is working, I might prune/edit the comments that are redundant.
Giant template-driven comment blocks at the tops of files and before each function are useless.
One of my pet peeves is when people comment the interfaces with implementation details, and the implementation details with instructions for use. If youāre in C++, where prototypes are often separated from implementations, itās good to think about the appropriate comments for each context. People looking at the prototypes are trying to figure out what your function does and how to use it. Developers looking into your implementation need to understand how it works and why you made certain decisions.
The commentless Newton-Raphson example could still be improved with a comment that says Newton-Raphson. At least thatās something someone unfamiliar with the algorithm can search on.
Good timing. I was just hired to add a video snippet of code into someone elseās website. The previous developer most have thought it was cool to reformat all of the code into one single line with no spaces or comments. Itās a mix of bad ASP and HTML. So now I believe the previous guy knew he sucked and just wanted the code to be difficult to edit by the business owner.
So the ethics question is should I just insert my properly coded, commented, indented and extra white lines of code into the other guyās jumble of mess? Or should I spend the extra time on the previous developerās code and force line breaks at all of the right spots, create indentions at all of the right nestings and add comments as to what I think he meant to do???
Well this client happens to be my friend on my weekend soccer team and I think Iāll extend the courtesy to clean the entire page.
My take on commentsā¦
I give my clients the If I die speech each time I run a project where they are given complete access to all source code, source images and help files for easy transferance to any other programmer. And within the source code there is just enough comments to help a decent programmer. And within the source images, there are just enough comments on each layer to help a decent designer. When I mean decent, I mean that the comments are not too long or descriptive to help a non-programming business owner think that they themselves could attempt to make code changes. (dangerous).
I always heavily comment my code. Itās not just for people to follow behind me. No. Its because 2 weeks later Iām knee-deep into something totally different and when I return to the previous code I need a gentle reminder.
As far as not having comments in your code, couldnāt you use a comment stripper as part of your automated build process?
Here is another one:
Identi-doc: Author tediously annotates each modification with their date/initials.
I donāt know how many times Iāve seen this! Please everyone give that one up.
Heh, arenāt function names themselves an abstraction designed to succinctly describe a block of code to programmers, just like comments? I mean, computers donāt really care if you call it SquareRootApproximation, foo or 0x00401000.
Saying comments are bad is like saying coding is bad. There are intelligent and stupid ways of doing everything.
Also, C#'s /// syntax is arguably superior if you want to add descriptions to the autocompleter or to API docs. You canāt make function names link to a Wiki article on Square Root Approximation. Why settle for that, when you can have an actual description in plain english and rich text markup support?
Please, pass the approximation threshold (t) to the private method.
I think ApproximateSquareRootOf( n ) would be even better. I always tell my developers that code shouldnāt need comments. Methods should be small and well named, the best ones should read like English inc which case the code becomes the comments. Complex methods almost never exist. They are instead simple method comprised of still smaller and simpler methods.
Conditional clauses are my favorite. They almost never tell you the intent:
if( lstItems 0 lstItems != null ){}
gives me a lot of technical details.
if( this.AccountIsSelected() ){}
private bool AccountIsSelected()
{ return lstItems 0 lstItems != null;
gives me so much more information. And hiding that clause in a method lets me abstract away those details if Iām a maintenance program so that I donāt need to keep everything in my head. Is the program having a problem with the account a user is selecting. No? then donāt trace into that methodā¦
There is a fatal flaw with your example. When you named the method SquarerootApproximation the information about which approximation you are using is
If you made a mistake or there is some problem with that approach then youāve just lost some vital information! Oh course NewtonSquareRootApproximation is not appropriate since thatās an implementation detail.
The point of the article should be what information should be expressed in comments and what should be expressed through refactoring, method names, and variables. It seems to me that there is NEVER a method that needs no comments. After all what does your method do when the number is negative? There should always be some comments, but always try to see how much of it you could express in other ways.
Thatās my $0.02.
I think the Spartan Programming (http://www.codinghorror.com/blog/archives/001148.html) approach also applies to comments. For C#, I use the XML documentation comments and then I decompile my assemblies using Reflector. If the code and documentation that show up in Reflector arenāt understandable, I refactor my code and revise my documentation until I canāt make it any better. Then, if thereās still something that isnāt clear, I comment it.
Totally in agreement. I take comments in general as an indication that the code itself has not reached its perfect state of self-evidence.
I attended a panel with the authors of Beautiful Code not long ago, and one of the authors mentioned that in his opinion, the only valuable comment in code was do not change this!..
I agree with Jeff ā¦ up to a point. If you can document the code using the code itself, then you absolutely should, and comments that simply reiterate what the code says are an abomination and should carry the death penalty.
Having said that, in my actual programming work I tend to use comments as commentary ā¦ at intervals, come up for air and jot down a note on where youāve got to and what the state of the system is. I would say the code describes what the program is doing, the comments describe what the programmer is doing if I didnāt suspect it of being a nice but meaningless sound bite. Comments donāt appear every line, but generally before a compound statement, if/switch, function call or group thereof.
The last comment I wrote, incidentally, was A push of CS in 16-bit code is taken to imply a near call to a far function. Provided the next instruction is in fact a near call, we can just ignore it. I donāt think youāll make the code that does that look like the comment that describes it.
I am, occasionally, guilty of the silly:
// What do you call a function written by a chav?
void init(void)
ā¦
if your feel your code should be if you feel your code.
Excellent post. Thanks!
While I agree that meaningful method names are a big step in the right direction, meaningful variable names are just as important. In your example I have no idea what n, r, or t mean, or why youāre performing those operations.
As Jeff points out, comments are ok, but the need to tell us WHY something works. WHY did we do it this way? WHY did we take the sub-optimal path. WHY shouldnāt I change this code at a later date?
Take this example from real-world code:
byte[] docBytesHash = MD5.Create().ComputeHash(docBytes);
StringBuilder sb = new StringBuilder(32);
for (int i = 0; i docBytesHash.Length; i++)
sb.Append(docBytesHash[i].ToString(x2));
What is does is somewhat obvious, and may net even need a comment. But how 'bout this:
//remote machine seems to use case-sensative comparison
// donāt change below to be X2.
byte[] docBytesHash = MD5.Create().ComputeHash(docBytes);
StringBuilder sb = new StringBuilder(32);
for (int i = 0; i docBytesHash.Length; i++)
sb.Append(docBytesHash[i].ToString(x2));
That comment tells me somthing that no code could tell me. It tells me about a dependency on a remote piece of code and a reason WHY something is coded that way.
I havenāt added a single comment, and yet this mysterious bit of code is now perfectly understandable.
The fact that this is bs, because the approximation algorithm is non-trivial, has been well covered.
But I would also add that the new code is also missing any sort of explanation for why you would use this thing. Of course, I suppose Jeff could add that to the signature as well
r = calculateApproximateSquareRootBecauseCallingSqrtDirectlyReformatsTheHardDrive(n)
Jeff, please learn the difference between documenting the (intended) interface, and code comments: documenting some possibly weird lines of code.
After that, you may come back to talk about code with no comments and Iāll be happy to read your blog again.
Your first pseudo-example for excess comments proves my point: Two lines of the comment are actually interface documentation, the rest is either implementation detail (which could be easily extracted from any actual code here, I hope), information which you could get more reliably from your source control system, and totally irrelevant stuff which you just made up, probably because without it it didnāt look worse enough to prove your point.
Although, I must admit I didnāt quite get your point yet - maybe we need to add more comments.
Good article, I often will use comments as little notes to myself as I go. They usually melt away once I refactor the code pending passing tests.
ps. Those scoping braces on the same line as your statements are cringe inducing. Blech.
The first time I had a copy of Code Complete in my hands, somebody had told me You can really just open it to a random page, and there will be wisdom there. Itās uncanny. So I tried it. I picked a random spot in the book, and opened to a section that discussed commenting code. What it said was something very similar to your argument. Paraphrased from memory, Comment to your code. Then rewrite the code so it doesnāt need those comments. Then comment that.