TITLE: No Comment? AUTHOR: Eugene Wallingford DATE: September 22, 2004 2:24 PM DESC: Programming places a burden on the writer and the reader ----- BODY: I just read a long rant by a student who is studying Paul Graham's ANSI Common Lisp. He was trying to understand an especially Lispy piece of code and having troubles. At the top of the code file he submitted, he included a comment over a page long talking about code readability, comments, and mental sanity. I enjoyed it very much. Many folks who have studied "advanced" Scheme or Lisp code know what he is talking about. I use the scare quotes because, while students often characterize the code this way, the code doesn't really have to be all that advanced to create this kind of disorientation. It doesn't have to be Scheme or Lisp, for that matter; I had a similar experience when I studied Haskell programs. It's more about programming style and familiarity than language. (Perl may be an exception. Does anyone really understand that stuff? :-) Functional languages tend to cause the kind of disorientation that my student felt, because we don't teach or learn functional programming very much or very well at most schools. Almost everyone who comes into contact with functional programming does so from a position of weakness. That's too bad, because functional programming can be powerful and beautiful, and as time passes we see more and more elements from functional languages migrating into popular languages like Java, C##, and Python. I'm glad that the TeachScheme! folks are building tools and developing techniques for teaching this stuff better. That's really just a prelude to what triggered my writing on this topic, which was the part of the student's rant that dealt with comments. He felt that, if Graham had commented the function in question, understanding it would have been easier. But as I read further into the rant, I found that much of the student's misunderstanding arose from his not understanding graphs and graph search as well as he might. Graham could certainly have explained more about graphs and breadth-first search, but his function isn't a textbook; it's a Lisp function. He could have added a comment with a pointer to explanatory material, but I suspect that Graham assumed his readers would already know certain CS basics. He is trying to teach a certain audience how to program in Lisp effectively, and perhaps something more general about programming. But teaching data structures and algorithms isn't one of his goals. Commenting code is a perennial topic of debate among programmers, students, and instructors. How much is too little, enough, too much? Brian Marick wrote a nice little piece that points out something folks seem to forget occasionally:
But code can only ever be self-explanatory with respect to an expected reader.
When writing code, you have to know your expected audience, but you also have to know something about other potential readers. Then you have to make some hard decisions about how to write your code and comments in light of all that. I don't expect that my students put a lot of comments in the code they write for class. Their expected audience consists of primarily me, with themselves and their fellow students as other potential readers. I don't need them to explain to me how a for loop works, or what an assignment statement does. I much prefer that they choose variable names and organize their code in ways that make their intention clear than that they add gratuitous comments to the code. On the other hand, I sometimes put comments in my code that reflect the fact that I am teaching students about some idea. If my code example is for CS I, then I may well comment a for loop with explanatory material. For CS II, I may add comments that explain the role played by a class in the Decorator pattern. Even so, I sometimes don't add comments of this sort, because the code is read as a part of lecture notes that explain the ideas behind the code. Maybe I should be more conscientious of the fact that many students will read the code of the context of the lecture -- or not even read the lecture at all! As I responded to some of my student's rant, my mind shifted to the old questions: Just when are comments most useful? When should programmers comment their code, and with what sort of comment? Let's assume that the programmer is writing for readers of roughly her own level of skill and understanding. I surfed on over to a wiki page I first read long ago and have always loved, Method Commenting. Ward Cunningham started that page with some patterns of code and comments to summarize a discussion of the topic. These patterns resonate with me. The basic theme is that people read code, and you should write for them. Code should reveal the intentions of the programmer, using names and method decomposition that communicate purpose. For example, one of the things my student disliked in the function he was studying was its lack of data abstraction -- the function uses cars and cars all over the place, which are implementation details. The code would read better with Syntax Procedures for the abstract path operations they implement. That said, programmers have to learn how to think like the machine. Programs aren't novels; they aren't even how-to manuals. A reader can't expect to have normal computational behavior explained in comments. What counts as normal depends on many things, including at least the programming style and language. Here is a situation that calls for a comment: Sometimes, you have to write code for the machine, for example, when an optimization is required. This code may mislead the reader. So, give the reader a clear warning in order to avert a misunderstanding. Here's another: Sometimes, you can take advantage of a given specification, say, a limit on the size of a collection, and implement an especially efficient algorithm. But the spec may change, and the code may then become a liability. So, fence off your code by documenting in a comment the constraint and its role on your implementation. (These days, I find that my unit tests serve this purpose better, and they are code!) There are some other situations where I use a comment, but they usually involve process. Sometimes, I have to leave a piece of code undone. A comment can help me know what is left to be done. Other times, I have a great idea that I don't have time to explore at the moment, and a comment can help me remember the idea. But I worry about both of these kinds of comments, because they tend to have a short lifespan of utility. If I don't get back to the same code soon, the comment on my great idea may not mean much to me when I get back to it. Or, worse, I don't see the comment until after it's too late. I usually prefer to make a note to myself in some other form for such things. When else is a comment better than (better) code? -----