6

I don't have a formal computer science education, meaning that I did not study computer science topics in a university. However, I work at a programming job and write a reasonable amount of code. Naturally, programming means that I also have to document and comment my code.

The problem I seem to be having is deciding between two schools of thoughts:

  1. Comment the hell out of your code e.g.

    unsigned int subtractor (int subtractee, int subtractor)
    {
      /*                      
         - This function is a subractor and is used to subtract one integer
           from another.
         - In other words the case here is subtractee - subtractor.  
         - Please ensure that the subractee is larger then the subtractor
           because this function will have undefined behaviour for negative
           answers.
       */
       (The code here...)    
    } 
    
  2. The code that explains itself let it be (no need to comment) like in this example. Just use good meaningful names.

Perhaps this example code makes one think that option (2) is better, but programmers with experience on large projects know that sometimes only meaningful names are not good enough. I know some commenting at appropriate places is a good practice but is it also a good idea to comment like in (1) to describe almost all major methods/functions?

The reason I ask is that a senior colleague at work told me to do as in (1) but now I am reading Clean Code by Robert C. Martin and it actually pretty simply states that (1) is a bad practice.

There are many other questions about commenting on this website but this question is different from others on this website because I am asking about a specific way of commenting i.e. (1).

UPDATE: What is the downside of writing more comments, this way a complete newbie can also understand it and also an advanced programmer (if he/she wants to read the comments anyway). But I understand that the advanced programmer will probably get a headache because he/she might read what they already know or can figure it out from the code anyway.

Another downside I can foresee is that the more you comment the more the chance that it might contain errors which can lead to confusions, but other good reasons we might have to comment miserly?

6
  • 7
    By the way, usual style is for functions to have verb-like names: when reading code, subtract (a,b) looks much more natural than subtractor (a,b). Apr 28, 2016 at 15:11
  • That really depends on the target audience. You should comment, 1) to remind yourself, what the code is about and 2) make others understand, if the code is going to be read, modified, and maintained by others.
    – Shreesh
    Apr 28, 2016 at 15:13
  • 6
    A code with no comments at all is better than a code drowned with trivial ones. Apr 28, 2016 at 16:52
  • All of the comments in your code produce the opportunity for the metadata to lie about the current state of the code base. Your commentary belongs either in commit annotations with a change set or in the associated work item. These are automatically synchronized through history because your change sets go into SCM additively. In the long run, I can see very plainly whether or not a "subtract" method can produce a negative number. There is zero need to declare to me within the source that code does not do what the code does not do. Apr 28, 2016 at 19:37
  • ...There should be zero need to declare to me that a method called "subtract" with two numeric arguments will produce the result of subtracting the two numbers. There should be zero need to explain to me that the error that occurs when a negative number is produced will produce an error unless your code is exceptionally sloppy and obfuscates this fact. Now...*why* it produces an error has meaning, but why doesn't belong in code. Why belongs in your repository of work items that you used for tracking your implementation of the system. Apr 28, 2016 at 19:40

6 Answers 6

26

I always tell my developers to comment the "Why?" not the "What?" or "How?".

I can always figure out what something is doing from the code. But it is much more difficult to figure out why it was done.

So many times I go to fix a bug and find that the code that causes the bug seems to be deliberate. I then have to worry what other behavior (that is currently relied on) will break as I fix this bug.

A comment saying what the code does is of little use to me at that point, but a comment saying why the code is there is very useful.

For maintainers (which is really who we put comments in for), "why" comments are really what is useful.

UPDATE:
Some also say to comment "What/How" on your tricky code. (Things that would be hard to figure out.) I agree with that as long as you cannot make the code "non-tricky" and still fulfill the requirements.

An example of this is if you had to make some code harder to read in order to meet a performance requirement of the application.

UPDATE II:
"What" comments can easily atrophy as maintainers change the code and not the comments. This is why copious amounts of comments can be a bad thing.

"Why" comments don't usually atrophy because even if the need/reason for some code/functionality changes, the "why" comment still tells the maintainer what the reason was at the time of coding (and leads to knowing if it is still needed).

4
  • I would agree with documenting the "why", but only in cases where the reason is not obvious. Apr 29, 2016 at 14:38
  • 6
    @LarryHector: Many things are obvious to the person who wrote the code that are not so obvious to the next person who has to read the code later. Apr 29, 2016 at 15:08
  • 1
    +1'd : I'd also include comments for documentation generators like sandcastle and phpDocumentor that can be used by IDE's to give useful hints to consumers of your function (even if that consumer may be you, five years from now). Apr 29, 2016 at 16:58
  • 1
    Even better, when applicable, is to comment the why not--ideas that were considered but recognized as unworkable.
    – supercat
    Jul 8, 2019 at 20:32
13

My experience is that there are 2 kinds of comments that are useful. The first kind is essential and that's when you need to explain the purpose of something that seems totally unnecessary. For example, if there's a bug in a library that requires a unintuitive workaround. The second kind is commenting that explain how to use things. These are basically instructions. These are generally high-level and don't explain how things work but rather what use they have and what is required of the user.

I don't think it's useful to write lengthy comments about how code works or explaining trivial code (e.g. "getName: gets the name".) One thing I've learned over the years is that you cannot trust these kinds of comments, you have to read the code and follow it. At best it tells you what the author thought the code would do and at worst, it's completely out of date and wrong. When you work on a team, you'll often see comments that were written for the first version of the code and never updated. I don't even bother to look at these types of things. This goes for design documents too. If you feel the code is hard to understand, you should refactor it. A big thing is using descriptive and meaningful names. That can also be taken go too far. I know a guy who names things with nearly complete sentences and it's too much noise and makes the code difficult to read.

P.S. I remembered a couple of other comment types that are useful. When you have an empty block of code (say you want to hide the default constructor in Java) you should add a comment that shows that it's intended to be blank. Some devs and code quality tools get really agitated about empty code blocks. If you need/want to come back to something later, use TODO comments. They help you remember and let others know there's something unfinished.

2
  • 1
    I concur with most of this. I disagree with the value of commentary that explains how to use things. Inspecting your tests should provide this insight without the risk of the methodology becoming out of date (if the system changes around the implementation of the test, then the test will naturally fail) Apr 28, 2016 at 20:12
  • 1
    @K.AlanBates I definitely get where you are coming from and I intended to convey that unlike the first type of comment, these aren't strictly needed. Here's an example of what I would consider a good use of comments (really class documentation): docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html. I don't really think it's realistic to expect everyone to look a unit tests to understand how to use a library. Of course, most developers are not writing libraries such as this but I think a lot of OS projects could be improved by better class and method level comments.
    – JimmyJames
    Apr 29, 2016 at 13:50
6

How much stitches should a human have in their body? Ideally none - as advanced as medical technology has become, poking holes in your skin to stick foreign objects in your body can't be that healthy, and they are not very comfortable. But if you have an open wound, you'll still want to stitch it(or use some other method to close it). You wouldn't refuse the stitches just because normally don't want them in your body. So, to answer my question - humans should have in their body the minimal amount of stitches required for stopping them from bleeding to death.

Comments in code are the similar - you should have the minimal amount of comments required for understanding and using the code. If other developers (that includes you as well if you return to your own code after not touching it for 6 months) can't understand your code because it was not commented enough - than you have too little comments. If you have too much comments, then by definition you have comments that aren't needed for understanding and/or using the code. These comments are wasting your time for writing them, wasting the users' time for having to read them, and wasting the maintainers' time for having to maintain them(or risk the comments going out of sync from the code).

At this point it should be noted that if you have some tool auto generating help from your comments(be it a tool like javadoc that generates HTML files or an IDE's bubble tooltip), always assume that users of your classes and functions will look at what the tool generate, and document such that they will be able to understand what you code does just from the tool's output.

As for code that documents itself - it can indeed save redundant commenting, but that's not the point of this practice. I find that as a rule of thumb, if you can refactor your code such that it will document itself the result will be a better code. For example, consider this simple Python function for calculating the distance between two points:

def distance(x1, y1, x2, y2):
    return sqrt(  # root of the sum of the squares
        (x2 - x1) * (x2 - x1) +  # distance on the X axis
        (y2 - y1) * (y2 - y1))  # distance on the Y axis

(In this case the code is simple, and should be understandable even without the comments - but for the sake of the arguments let's assume is isn't)

Now let's refactor it to document itself:

def distance(x1, y1, x2, y2):
    delta_x = x2 - x1
    delta_x_squared = delta_x * delta_x

    delta_y = y2 - y1
    delta_y_squared = delta_y * delta_y

    sum_of_squares = delta_x_squared + delta_y_squared

    return sqrt(sum_of_squares)

This is a very basic code-that-documents itself technique - instead of commenting what each and every part of the expression does, I put it in a variable and gave it a name that explains it. I argue that this results in more maintainable code, because if it doesn't work properly you can run it in a debugger and look at the result of every part of the calculation(or just print them to STDOUT). I don't stay that every sub-expression needs this treatment - but if a sub-expression is non-obvious enough to be documented, it is also non-trivial enough to possibly be wrong.

Still, like stitches - if you really need comments you should put comments. No best practice should be followed to the letter at all costs(you can't do it with all of them anyways - they conflict too much), and that includes code-should-document-itself. Refactoring the code to document itself may result in a monstrosity(either because you did it wrong or because it can't possibly be done right), or simply be outright undoable. The ideal that code should document itself should never be used as an excuse for code that can't be understood due to lack of comments. This may sound silly, since it kind of defeats the purpose of this rule - but that's more often than it should the result of following best practices blindly.

2
  • 4
    I really like your analogy with stitches :-) However, for the refactoring example, I think you overdid the refactoring: You basically named the variables after their form within the expression. I would only define delta_x and delta_y, and then simply do return sqrt(delta_x*delta_x + delta_y*delta_y). That way, anyone who has not slept through all their math classes, will immediately see what's happening because the structure of the expression carries meaning. And that structure is lost with your code. Apr 29, 2016 at 21:49
  • @cmaster That's why I wrote "(In this case the code is simple, and should be understandable even without the comments - but for the sake of the arguments let's assume is isn't)". One can also argue that the entire expression is simple enough for anyone who has not slept through all their math classes to understand without neither the commenting nor the breaking down. For the sake of the example I wanted to break it down as much as I can, but in real life example the expressions you end up with may be longer then the expression I started with here, and still simple enough.
    – Idan Arye
    Apr 30, 2016 at 13:37
1
//Thoughts about code with too many comments
//I will give a reason to avoid using too many comments
//My reasoning will relate to the size of the source code
//I will also mention the need to update comments
//http://programmers.stackexchange.com/questions/317055/how-much-commenting-is-better-for-coding
// - user2023861
Here are my thoughts about code with too many comments

//checking if comments restate code
If you include comments that restate what your code is doing 

    //The size of the code will double
    Your code will double in size

    //code changes require comment changes
    When your code changes, your comments will also need to change

    //the code maintainer won't trust the comments and will ignore them
    This breaks the trust that a code maintainer may have in the comments

//The end of my hypotheical scenario
End if
1

I agree with Vaccano's answer. If would only add that someone will come around to your code after you're gone and they are likely to change it, and likely break it.

So I try to leave instructions to those who come after me. Why I did what I did and not something else, and how to make changes that I can foresee possibly being needed in the future. Those coders certainly appreciate it.

0

Actually "How much commenting is better [...]" is the wrong question. The right question is "Which comments are good, and which comments are bad?"

It's really not about commenting less, commenting more, or even about striking a balance, it's about including all the comments that are helpful to future readers, and about leaving out all those, which only add noise to the code.

So, how can we define a bad comment? I would put it this way: A comment is bad if writing/maintaining/reading it takes more time than its content saves time. This is always the case if the comment falls into one of these categories:

  • The comment repeats what is obvious from the code, a variable name, or a function name. The code exists anyway, and reading the code yields the information at the same speed as reading the comment does. Doxygen-style comments are a notorious offender of this rule, which is why I personally do not like these tools. But don't get me wrong, some Doxygen-style comments are good. It's not the style that matters, it's their contents!

  • The comment is out-of-sync with the code. It's clear why such comments should be deleted on sight, they are downright misleading. Unfortunately, it's frequently quite hard to realize that a comment has gone out of sync because you have to rule out the possibility that you just didn't understand what it means. Which makes those out-of-sync comments only more costly.

On the other hand, good comments include information that is not conveyed by the code itself. And the quicker they get their point across, the better they are. Examples include:

  • Comments describing intended use patterns for the code.

  • Comments describing architectural structures that are too large to quickly infer from the code itself.

  • Comments describing why the code does things the way it does them. For example, if the code is working around a compiler bug, it's not good if each person touching the code first refactors the cruft out of the code, only to realize that this cruft was necessary to avoid triggering an internal compiler error.

  • Comments describing what possible implementations have not been chosen, and why they have not been chose. These can save quite some time for future refactorers who would eventually come to the same conclusions as the original coder. Alas, these comments are rarely to be seen, and I'm as guilty of omitting them as anybody else...

As you see, you can easily write a lot of very valuable comments, or comment very sparsely and still be less than helpful. It's the quality of the comments that matters, not their quantity.

Not the answer you're looking for? Browse other questions tagged or ask your own question.