Cowboy Programming Game Development and General Hacking by the Old West

February 14, 2007

Comments vs. Self Documenting Code

Filed under: Cowboy Programming,Game Development — Mick West @ 10:20 am

I was reading a thread over on GameDev about the use of comments. There were a variety of opinions, ranging from the extremes of “comment every line of code” to “code should be self documenting and have no comments”.

Personally I use quite a few comments in my code. Game code tends to involve the interaction of a large number of complex systems. Self documenting code is really only a reality if you are insanely familiar with the context of that code. That’s plausible for a period of time, on smaller projects. But for large game projects, especially console games, that often use code that has evolved over several years, and interface with several third-party middleware libraries, it’s really not practical.

What do real code gurus say about commenting code? Steve McConnell has a whole chapter on “Self Documenting Code” in Code Complete 2, which covers the cases for and against comments, concluding (page 817:

The question of whether to comment is a legitimate one. Done poorly, commenting is a waste of time and sometimes harmful. Done well, commenting is worthwhile

In The Pragmatic Programmer Hunt and Thomas say (page 249)

In general, comments should discuss why something is done, its purpose and its goal. The code already shows how it is done, so commenting on this is redundant.

In The C++ Programming language, 2nd ed., Bjarne Stroustrup (the creator of C++) says (page 139)

A well-chosen and well-written set of comments is an essential part of a good program. Writing good comments can be as difficult as writing the program itself

Jef Raskin, Creator of the Apple Mac project, says (here)

Do not believe any programmer, manager, or salesperson who claims that code can be self-documenting or automatically documented. It ain’t so. Good documentation includes background and decision information that cannot be derived from the code.

The question of “Comments vs. Self Documenting Code” is a false dichotomy. You want both. If your code is really so messed up that it needs lots of comments, then it’s smelly code, and may be ripe for refactoring. Obviously it’s a good thing to have meaningful identifiers in code, and to avoid stating the obvious in comments. But if you can clarify something with a comment, then you should.

Unfortunately dogma is something you find often in programmers, even in good programmers. “Goto considered harmful”, “premature optimization is evil”, “comments indicate sloppy code”, “pointers are evil”, “singletons are evil”, “multiple check-outs are evil”.

All these things: goto, early optimization, comments, pointers, etc., are useful tools. They can also be dangerous tools. They can be over-used, and mis-used by bad programmers. Hence simple minded programmers (and managers) rail against them, and impressionable programmers regurgitate the dogma without really understanding the reasons behind it.

Read Code Complete 2, it’s all you need to know (which is quite a lot).

12 Comments »

  1. Now, I’ll state right now that I don’t work in the game development field. Its not a field that I’ve got a whole lot of interest in entering, mind you.

    I do however tend to end up having to work on some very large systems that are enterprise based (over 10kkloc in some cases…its horrible the sins that can be committed with C code). Now, as you may note from that thread, I’m not a big fan of comments… sort of.

    Comments aren’t an abuse really, they can be abused though, and I do see this a lot on GDNet. People write code using i, j, k, w, z and expect you to know what these variables are based on the COMMENTS they use. Even professional programmers do this, you can clearly see this even in books like Code Complete (which I also HIGHLY recommend reading…but you have to take everything said in it with a grain of salt, but I’ll get to that in a minute).

    Readability of code shouldn’t be sacrificed no matter WHAT platform you’re coding for. Just because you’re writing a game for console doesn’t mean you should write code like that…but yet you do (not YOU specifically, although you may be guilty, but plenty of others do). Code that contains meaningless names and naming conventions, code that uses comments to tell you what is going on, instead of clearly spelling it out in the code. Now, this isn’t always possible, as I noted in that thread. Sometimes you have to sacrifice readability for performance, and a decent set of comments there can help to ease the understanding of that code. But that’s no excuse to routinely sacrifice code readability.

    Ultimately we the programmers are responsible for writing code that can be maintained and reused elsewhere. If we’re writing messes like your blob code (which I think you’ll agree is a bloody mess) then we drive ourselves into the position of not being able to maintain that code, let alone debug it. Now, I’m a big proponent of test driven development, and it works. Since I adopted that strategy I tend to not hit the debugger for weeks on end. Why? Because my tests are catching my mistakes. Now sure, my tests can’t cover my code 100% (actually, it can be measured…managed code is great) but it covers it to an extent that I am confident in its ability to perform the operations required of it. Combined with integration and feature requirements testing, you have a set of powerful tools that can both speed up development time of features, and reduce the number of end bugs you have to diagnose. Furthermore, TDD forces code to be cleaner and easier to maintain, due to its evolutionary development approach.

    Sure, sure, you can’t apply TDD to games. It is all a lie though. You can apply TDD to games, maybe not to the WHOLE game, but to enough of it to make a difference. With the explosion of middleware, testing becomes even easier, mock the interface and you’ve got yourself a powerful method of testing new features without having to spend days in the debugger tracking down that stupid mistake you made.

    I also tend to comment my function declarations, because I can pull out that data and use it in preliminary API documentation schemes. But that doesn’t mean I should do such silly things as storing my documentation IN the comments (see doxygen), because by storing my entire documentation in the comments, I bloat the files up with useless information. You’re not going to be reading my file to see how to use the function; you’ve got my documentation in a nice .chm or other file type.

    As I also noted, I tend to keep a developers log, which is not in my comments. It’s a document, actually in my case it’s a notebook, where I record design decisions that were made, why, and potential consequences. People often store this information in comments, but its not useful as a comment because you can’t track it down.

    Comment by Washu — February 14, 2007 @ 11:37 pm

  2. I’m curious as to why you’ve spent years on gamedev.net giving your opinion regarding a field you have no interest in entering.

    I’m a big fan of readable code, especially meaningful names. Some people just seem to be adverse to typing, and abbreviate everything. However I see nothing wrong with using i for an iterator in the situation where it’s the sole iterator in the function. Also, x,y,z and w obviously have their usages when mirroring their algebraic equivalents.

    But yes, code should be readable, and comments help. You seem to be vigorously arguing against comments, while at the same time saying they are sometimes useful. What your argument boils down to is “writing bad comments is harmful”, which is a tautology, and not particularly useful.

    I’m not clear on what your position is on Doxygen style documentation. It seems optimal to me to keep the documentation in the function header comment. How is that bloating the file with useless information?

    Developers log: How is this notebook going to help you? And why a physical notebook? It seems a little hard to share with the team.

    Speaking of teams, I know you’ve worked in team environments, but it seems your strong adherence to few comments, and reliance on the self-documenting nature of your code, speaks to a very small cohesive team, or to solo work. In game development the team is often large, variegated and in flux. Code that is self documenting to you might be confusing to another team member. Explanatory comments are useful time savers here. Conversely, not everyone programs to your high standard, and you might appreciate some good comments in unfamiliar code.

    That’s the key: “good” comments.

    You said on gamedev.net that comments are only needed: “as a means of clarifying what might be a particularly complex operation that has resisted clarification through refactoring”. The reality is a bit more complex, which is why there is an entire chapter of Code Complete 2 devoted to the subject. Instead of misleadingly simplifying thing, you would do better to steer people towards that chapter.

    Comment by Mick West — February 15, 2007 @ 9:02 am

  3. I’m curious as to why you’ve spent years on gamedev.net giving your opinion regarding a field you have no interest in entering.

    Yeah, I get that question often enough. Ultimately the answer boils down to this: Developers come from all places, great and small. GameDev.Net tends to be one of the larger communities that is developer oriented (although we hope to change that such that its not just a programming haven but a haven to the full development process for games, any help or suggestions in getting us to achieve that end would be welcome). I also hang out in a lot of other places, such as comp.object, comp.lang.c++.moderated, and comp.std.c++ for example. But ultimately, the majority of newbies will be introduced to programming through something that they feel is fun. Games tend to be fun, so what better way to have fun than to develop your own games? Thus I try and dispense what knowledge I have to those newbies who visit gamedev.net in the hopes that those few of them with a real spark of potential will use that help to grow that spark into a full fledged conflagration.

    I’m a big fan of readable code, especially meaningful names. Some people just seem to be adverse to typing, and abbreviate everything. However I see nothing wrong with using i for an iterator in the situation where it’s the sole iterator in the function. Also, x,y,z and w obviously have their usages when mirroring their algebraic equivalents.

    Indeed! There is nothing wrong with i as an iterator, x, y, and z as variables or vectors, heck, I’ve even used latex subscripting before when writing out mathematical expressions in various languages. The problem as I see it revolves around what we teach our young protégées though. Do we teach them to use meaningful names and to write code that is clean and readable? Or do we point them to books like “Game Programming All in One” or other such examples that claim to teach you everything you need?

    But yes, code should be readable, and comments help. You seem to be vigorously arguing against comments, while at the same time saying they are sometimes useful. What your argument boils down to is “writing bad comments is harmful”, which is a tautology, and not particularly useful.

    It is hard to put exactly what I’m trying to say into words, but I’ll give it a shot: People often use comments as a means of excusing themselves from writing clean code. As code complete notes, your code should say HOW it works, but your comments should say why you’re doing it. But more often than not I encounter code that says nothing about the how or the why of the code, and a heck of a lot about why the previous programmers quit. It does tend to have plenty of comments though detailing the HOW of it.
    That being said, a good comment can be worth a thousand lines of code, or an hours work of prototyping and testing to understand the various ways in which a piece of code will be applied. But it shouldn’t be detailing why you’ve decided to use a state pattern. That information should be more centralized, in a place easy for everyone to access.

    I’m not clear on what your position is on Doxygen style documentation. It seems optimal to me to keep the documentation in the function header comment. How is that bloating the file with useless information?

    It does? Imagine for a second that the MSDN documentation was embedded in the API headers, would this be optimal? Hardly, digging through those headers is already a pain, littering it with comments just exasperates the problem. Now, preliminary documentation, or interface documentation tends to be a good idea though. Sometimes you just right click -> Go to definition. Which takes you to the function declaration and BAM, you’ve got a nice comment there that tells you what the parameters mean. I certainly wish ruby’s C interface had such niceties. But a full documentation of the function and its corner cases and the various other issues it might have tend to be outside the scope of a comment block. It just doesn’t belong there.

    Developers log: How is this notebook going to help you? And why a physical notebook? It seems a little hard to share with the team.

    I actually keep both a document (that’s in source control), and a notebook as well. The notebook is nice because its something I can flip through while I’m in a design session with other architects, to look at past examples, and because I can scribble in it, make crude drawings and drafts next to various decisions. Those drafts can later be turned into nice diagrams which get embedded into the document. But scribbling around on paper is a lot faster than drawing in paint or Visio, and it gives me time to relax the hands.

    Speaking of teams, I know you’ve worked in team environments, but it seems your strong adherence to few comments, and reliance on the self-documenting nature of your code, speaks to a very small cohesive team, or to solo work. In game development the team is often large, variegated and in flux. Code that is self documenting to you might be confusing to another team member. Explanatory comments are useful time savers here. Conversely, not everyone programs to your high standard, and you might appreciate some good comments in unfamiliar code.

    Depends, the projects we work on tend to be divided up such that many small teams can work independently with an architect per team. These teams produce artifacts that the architects write integration and feature tests for, thus ensuring that the end product both integrates properly, and that the features that the customer requires are in place. Since we involve the customer heavily in the process of feature determination throughout development, the customer ends up helping to write (and often actually writes a large chunk of) the acceptance tests (feature tests). We’ve found this method tends to help build a much more agile set of components, even when the application gets to be very large.

    Actually, the reality is that refactoring can’t simplify all problems. It can make some particular design decisions clearer, it can make some code problems clearer, but it is not a silver bullet. Some problems resist refactoring simply because of the problem. In those cases, a good comment can save minutes of useless refactoring, and hours of a maintenance developer’s time. But yes, you are also right in that there are other cases where comments are appropriate. Let us take for instance the volume of a parallelepiped, it can be taken as either the absolute value of the scalar triple product, or as the absolute value of the determinant of a 3×3 matrix such that the row-vectors are the axis vectors of the parallelepiped. Now, which one do you choose? Which one is simpler to code, and which one is more efficient? It turns out that both reduce to basically the same code, so you can choose either and be equally as efficient. But which one is clearer to the viewer as to what you are trying to do? Who knows, but a nice comment explaining WHY you chose the determinant method over the scalar-triple-product would go a long way to clearing that up. This is a decision that really doesn’t belong in the developer’s log, as it is not really a design decision, more of an algorithmic one. These are things I would put comments in for as well. The same thing is true of your choices for data structures. Lets say you chose std::map over std::tr1::unordered_map, you would probably want to make note of the WHY there… “//Need worst case complexity of O(log n) for lookup” Perfectly acceptable, and in fact I would say that it should be encouraged.
    But teaching people how to comment is hard. VERY hard. It is just like coding, but you have to be far more careful, since your comments may make or break another’s understanding of the code to which you have applied the comments. So, instead of saying “yeah, you should use comments” I would rather say “Write clean code. Then worry about comments.” However, I should really say is this “Write clean code, comment clean code, read code complete 2nd edition.” Except I’ve found that for most newbies that doesn’t work. They want to write their games starting in C++ and using “Learn C++ in 21 Days” and “Game Programming All in One”. But you are right, I should be clarifying how to comment more than just discouraging it.

    Comment by Washu — February 15, 2007 @ 10:07 am

  4. Nicely put. Newbies of course don’t get the big picture, and can be quite impressionable. Which is why I get annoyed when I see what seems to be simplifications. I’ve worked with people where their initial exposure to some half-baked methodology has ossified into dogma. This is why I place “methodological” below “pragmatic” (and only slightly above “delusional”) in my (tongue in cheek) Seven Stages of the Programmer

    Most newbies, unfortunately, are still at stage 3, “Fumbling”, poised for an inevitable journey through “Delusional”. One can only help them avoid a few of the obstacles.

    Comment by Mick West — February 15, 2007 @ 11:54 am

  5. A GameDev.Net thread about comments that I missed! How blind I am! :)

    I’m also quite proud of my ability to write code that needs very little comments – but I’m ashamed that when I need to write comments, they are often poor and uninformative. I blogged on this subject a while back (sorry, it’s in French…) and I got a comment back (no pun intended) that I found quite interesting. The comment roughly said: “the comment you want to write to document a function shall be written before your write any code”. It makes sense, since you have no choice but to express your intent – you have no code to paraphrase, so it should be easier. Moreover, it’s often when you need to write a function that you have the best comprehension of what it should do – once it is written, your brain doesn’t keep track of the creation process, and most of the time you forget the original goal of the function.

    Of course, it’s a bit difficult to apply this practice when you want to modify an existing function.

    Comment by Emmanuel Deloget — February 22, 2007 @ 5:43 am

  6. The comment roughly said: “the comment you want to write to document a function shall be written before you write any code”. It makes sense, since you have no choice but to express your intent – you have no code to paraphrase, so it should be easier.

    That’s fine in limited way. But in practice there are a number of objections to that idea:
    – If you are implementing something described in comments, the comments may become partially redundant
    – Decisions in implementing a function may be made after the initial comment is written, which will require a change to the comment, or an additional comment.

    In Poker there is a theory that says your ideal bet should be what you would bet if you knew what your opponent’s cards were. While this is obviously impossible, it still serves as a yardstick to measure your actual bet by.

    Similarly with comments – perhaps the ideal comment would be one you would write before the code is written, but as if you knew exactly what code you were going to write, even if you actually write it after the code is written.

    Comment by Mick West — February 22, 2007 @ 8:36 am

  7. If you are implementing something described in comments, the comments may become partially redundant

    Of course comments describing the implementation will be redundant, but I totally disagree with the notion that this might be a bad thing.

    This seems to be the main argument behind the “my code is self documenting” camp: comments = redundant = bad.

    I don’t care how clear anyone thinks their code is, it’s always going to take more lines of code to explain something to a computer than it takes lines of English to explain the same thing to an English-speaker. The reason for this is that language can be vague, but code cannot be.

    If you don’t write comments, you are basically forcing everyone to run your code in their head, reverse engineering to understand it. Good programmers ought to have the skill to do that, but nobody wants to have to read code when they can just have someone else explain it to them. In fact I’ve seen plenty of cases where people just go off and write a brand new version of the same code just because they didn’t want to have to reverse engineer the original. Usually because the original didn’t have any comments and the guy who wrote it quit.

    Please please please if you believe your code is so clean it does not need comment, step off the ego horse and help your fellow programmers out by putting some comments in anyhow.

    Comment by Eigenvector — July 9, 2007 @ 11:44 am

  8. I think really what comments need to convey is your thought process whilst writing the code. I agree with the Pragmatic Programmer mantra. I comment my code because I often come back to something six months later and can’t remember why I wrote it exactly like that. What was I thinking that day? By the time you finish reading the code you should understand where the person who wrote it was going with it. Long, complex projects are often a learning experience and the simple concepts you used at the start may evolve.

    It’s interesting when people say they don’t need to comment their code. As mentioned earlier, in a small cohesive team, or solo, perhaps you can get away with this because you all talk so regularly and you’re sitting 6 feet away from the guy who wrote it. I’ve worked in teams like that and it does work if you can nudge that guy and ask him a question. But what if he leaves?

    If you’re on a 50 programmer team, chances are on a big team everyone’s code is interleaved with everyone else, and then you’re in the position of perhaps trying VCS history to find who wrote those lines, etc, etc. And when you do find that person, will they remember why they wrote those lines? So the point is about communicating your ideas to other people, albeit concisely. If you need to write an essay, or convey user documentation to end users (e.g. designers or artists) then there is the wiki. If you based something on a paper or external web link, cite it.

    It’s pointless (and distracting) when people explain exactly what the code that follows says (i.e. not why it was written). If it doesn’t add anything to what the source code says then a comment is almost worthless. What we need is the _purpose_ of the code. What were you _thinking_ when you typed those lines in. As we travel through the execution of the code what is the sequence of events?

    Comments detailing the future plans for code are useful, perhaps to save wasted labour, or find out what you’re getting into. E.g.


    // Bob: Jim asked me to fix this function for milestone 4. Time was tight
    // so I've gone for a simple fix and made the array bigger. Really this
    // should be made into a linked list but too much to do.

    // Andy: I haven't written an algorithm like this before so I've done my
    // best to keep it simple. Please let me know if you have any problems.

    // Ted: I'm going to rewrite this class when I get time. System X is
    // being refactored because it uses too much memory which means
    // this class needs changing.

    // Fred: I fixed a threading glitch in here with a mutex but performance
    // is terrible. Need to refactor this whole class.

    I think one of the main reasons people don’t write good comments is they don’t schedule for them, or under time pressure they are the first thing to get cut. Good commenting involves examples (code snippets) and samples (full programs) which takes a lot of time. Rapid explanation of what is there, after the fact, takes less time, and a lot of programmers would rather just program.

    Also, as mentioned, a lot of people think their code doesn’t need explanation. One trick I learnt is to go and get a coffee and when you come back, imagine you are sitting down to look at the code you wrote for the first time (as though you are someone else). Now fill the comments and examples you think you would like to see.

    Comment by Nick — October 23, 2007 @ 3:50 am

  9. Hello everybody, my name is Damion, and I’m glad to join your conmunity,
    and wish to assit as far as possible.

    Comment by DamionKutaeff — March 22, 2008 @ 12:00 pm

  10. Who are you more than you think i got out ofthe bus. And pushed cum on feet her. Who are you little flirt. Not make me cum very excited.

    Comment by cum — April 5, 2008 @ 11:01 pm

  11. win super bowl tickets

    Comment by acotvybuge — November 13, 2008 @ 1:59 pm

  12. I think the answer is simple.

    1) Write self documenting code _at all times, regardless.

    2) Create javaDoc style long comments for each and every function/method. This way you can run a tool to autogenerate API documents, at the same time comment your code!

    3) Do NOT comment every single line, or every other line. Instead, use point #2 I mentioned above. For a complex LOOP algorythm a couple lines of comments may be good. HOWEVER, if the LOOP or if/else code block is so non-obvious, maybe it needs to be refactored into a function/method! in which case point #2 will satisfy the commenting.

    Comment by Matt Kukowski — January 16, 2010 @ 3:55 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment

You must be logged in to post a comment.

Powered by WordPress