No comments

“Comments should be 5% of the total score,” said my fellow professor.

In the fall of 2019, I was helping teach an introductory computer programming course and we had a disagreement over whether students should comment on projects submitted for review.

“I want students to adopt good habits from the start. Do you agree that adding comments improves the quality of the code? ”A colleague asked me, a little frustrated by my negative reaction.

I objected to him eagerly. Getting used to the obligatory insertion of comments is probably the most bad habit of programmers taught in universities. Apart from some cases in which the use of comments is justified (more on them later), adding comments is an anti-pattern, and over-commented codebases are likely to need refactoring.

Wait, what kind of heresy? Comments don’t bother anyone. Or do they interfere?

There are two reasons why I consider comments an antipattern:

  1. They will inevitably become obsolete. Developers forget to update comments when refactoring code and creating new features. When this happens, comments become the root cause of what should have been discouraged, which is confusion. This is especially true for large companies in which many people are actively changing the common codebase. Imagine the state of a newbie who cannot figure out why a house has a comment calling it a Palm Tree.
  2. Programmers (myself included) write redundant or bad comments. I have noticed this in every company I have worked for, and many excellent programmers are guilty of this. It was a rule of my team at Google that every protocol buffer definition must be preceded by a comment. Therefore, we had a bunch of code examples that looked something like this:

// Represents a Dog.
message Dog {
    // The id of the dog.
    string id = 0;
    // The name of the dog.
    string name = 1;
    // The breed of the dog.
    string breed = 2;

Redundant comments are noise that can make files twice as long as they should be.

Okay, your point of view is clear. Excessive comments are harmful. But what about when comments are needed to explain what the code is doing?

You can almost always find other ways to communicate what the code is doing. A generic strategy is to use appropriately named temporary variables or method names that convey their purpose. Let’s take a look at a specific code example. I’ll write it in Python because it most resembles pseudocode, but the concept is applicable to any programming language.

In this example, we send payment to sellers when certain conditions are met. For example, this might be an Amazon seller receiving the total payments for their platform sales:

# Seller is eligible to be paid under the following conditions:
# 1. It's past 2020/5/1 when we got legal approval to make payouts
# 2. It’s Nov/Dec since those are the only months eligible
# 3. User is not from list of countries that are banned
today =
if today > date(2020, 1, 1) and (today.month == 11 or today.month == 12) and not in ['Narnia', 'Odan', 'Maldonia']:
    # This function does the actual payout by calling Stripe
    # It saves the response asynchronously.

At first it seems that the use of comments is justified, because they increase the readability of the code. Code is read more often than it is written, so improving readability is a good thing. In this example, comments convey the following information:

  1. Payment conditions. Without a comment at the beginning, the reader himself would have to understand the parsing of the short subconditions in the conditional statement in order to understand whether the payment should be made.
  2. Why are specific constants used (2020/5/1, 11, 12 and [‘Narnia’, ‘Odan’, ‘Maldonia’]) and what they mean.
  3. What the payoutHandler () method does.

Now let’s see how we can rewrite this code so that it conveys the same information without using comments:

PAYOUT_APPROVAL_DATE = date(2020, 5, 1)
BANNED_COUNTRIES = ['Narnia', 'Odan', 'Maldonia']
today =
is_past_approval_date = today > PAYOUT_APPROVAL_DATE
is_eligible_month = today.month in ELIGIBLE_MONTHS
is_user_from_banned_country = in BANNED_COUNTRIES
if is_past_approval_date and is_eligible_month and not is_user_from_banned_country:
 stripe_payout_resp = callStripeToPayout(user)

Note that information that was previously passed in comments is now passed using temporary variables (is_past_approval_date, is_eligible_month, is_user_from_banned_country), constants (BANNED_COUNTRIES) and verbs as function names.

Proper naming is a powerful tool for replacing comments and helping you write self-documenting code. Now this code can be mercilessly refactored without fear that the house will be mistakenly described in the documentation as a tree.

That is, comments should never be used? Something too strict a requirement.

I use this rule of thumb: do not use comments that answer the question “what?” Use them to explain why?, and only in those cases when “why?” cannot be explained by names… In most cases, to explain why? well-chosen names are enough. For example, instead of adding a comment like this:

# This code removes the invalid control characters because the 
# AS400 processor cannot handle them

name your function

def remove_AS400_incompatible_control_chars():

If you cannot rely on names when transferring information, for example, if the code does something small or non-obvious, then the comments, of course, are justified. Here are some examples of helpful comments:

# Prevents a rare but severe race condition which happens when...

# Closing this write transaction before making the RPC to prevent stale locks

Perhaps you should examine your codebase for the possibility of replacing comments in it with self-documenting code.

Macleod proposes high performance servers for any task – up to 128 vCPU, 512 GB RAM.
Register using the link above or by clicking on the banner and get a 10% discount for the first month of renting a server of any configuration!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *