Norvig, Atwood, and Comments

This post was written by Jake on August 4, 2008
Posted Under: Politics, Programming

Steve McConnell on Comments

Jeff Atwood recently wrote an article on comments in source code. He discusses a few different approaches to commenting a Newton’s method square root function, and describes the pros and cons. His reasoning was (unsurprisingly) influenced by Steve McConnell.

Good code is its own best documentation. As you’re about to add a comment, ask yourself, ‘How can I improve the code so that this comment isn’t needed?’ Improve the code and then document it to make it even clearer.

~ Steve McConnell, Code Complete

Atwood goes through a few design iterations of a snippet of code and arrives at the following:

private double SquareRootApproximation(n) {
  r = n / 2;
  while ( abs( r - (n/r) ) > t ) {
    r = 0.5 * ( r + (n/r) );
  }
  return r;
}

This has been written about extensively by various bloggers, but nobody cares about what bloggers think. It logically follows that I don’t care about what I think.

I couldn’t indifferently agree more.

Rather than take a stab at improving the documentation of this particular piece of code myself, I wanted to improve it using someone else’s method. To do this, I engaged in an old hobby of mine: I researched the practices of people who are hell of a lot more successful than I am.

Knuth’s Literate Programming has always fascinated me, and I might someday use it to write a large program. However, it won’t be soon, and I sure won’t be using it when working with others. I also feel that its effect would be lost on an example this small, so I decided to pass on this.

In lieu of this, I found that Peter Norvig has written the best practical advice on comments.

Enter Norvig

Dr. Peter Norvig [bio] wrote a Tutorial on Good Lisp Programming Style [.ps alert]. This particular work is worth the read from beginning to end, but of particular use are his few commenting conventions. Some are Lisp-specific, but there are a few good lessons for the taking.

Be Helpful

“Documentation should be organized around tasks the user needs to do, not around what your program happens to provide. Adding documentation strings to each function doesn’t tell the reader how to use your program, but hints in the right place can be very effective.”

This has been very helpful for me in the week since I first read it. He also cites good examples from the Emacs documentation:

“next-line: Move cursor vertically down ARG lines.

… If you are thinking of using this in a Lisp program, consider using ‘forward-line’ instead. It is usually easier to use and more reliable (no dependence on goal-column, etc.)”

Declare the unobvious

“If you’re thinking of something useful that others might want to know when they read your code and that might not be instantly apparent to them, make it a comment.”

This is related to the above. Anything that a person might need when using your code should be mentioned. If you had to derive your code, the method should be described (even if briefly) so that a maintainer may double-check your work.

Say what you mean

Speak in declarations and assertions. Use appropriate detail. Be explicit. Not much to say here.

Applying it to the Code Sample

There are two different ways that I would comment this code. If the interface and the implementation were separated such as in C++, I would add different comments for the header file and the source file:

Header

/* Approximates sqrt(n) to within the specified error.
 * Convergence is quadratic.*/
private double SquareRootApproximation(double n);

Source

// Approximates sqrt(n) using Newton's method.
private double SomeClass::SquareRootApproximation(double n) {
  r = n / 2;
  while ( abs( r - (n/r) ) > t ) {
    r = 0.5 * ( r + (n/r) );
  }
  return r;
}

We could also be using a language where the interface and the code are the same. I would comment like this:

/* Approximates sqrt(n) using Newton's Method
 *      to within the specified error.
 *
 * Convergence is quadratic.*/
private double SquareRootApproximation(double n) {
  r = n / 2;
  while ( abs( r - (n/r) ) > t ) {
    r = 0.5 * ( r + (n/r) );
  }
  return r;
}

So is this helpful, declarative, and straightforward?

I think so.

Giving the user the convergence is simply being considerate. We just as easily could have developed a linear method using fixed-point methods, or any method for getting super-quadratic convergence.

Without the comment, it would simply be an implicit assumption that this was “fast”, for some value of fast.

We also stated (for the maintainer’s sake) that we are using Newton’s Method. The maintainer could verify that the code does what you claim it does, replace it with his favorite super-quadratic convergence sqrt() function, or ignore it because it’s too mathy.

The example is also concise, in that Mr. Atwood’s rearrangement of the code allowed a few little comments to convey a world of information.

Popularity: 10% [?]

Reader Comments

Trackbacks

  1. Websites tagged "think" on Postsaver  on October 27th, 2008 @ 3:47 pm

Add a Comment

required, use real name
required, will not be published
optional, your blog address

Previose Post: