Comments Are The Only "Code Smell"
Tags: codequality, codenewbie, tutorial, beginners
Published: 2020-10-08 03:09:41

My regular readers (both of them) may notice that my _previous_ article basically disavowed the idea of the "code smell".  The term is too often a smug, arrogant, dismissive mantra that serves no meaningful purpose.  So why is my _very next_ article dedicated to, what I believe is, an actual code smell??  Well, on one level, I'm more than willing to troll _myself_ from time to time.  But on another level, there is really only _one_ aspect of programming that I routinely view as a "code smell":  Comments.

You may have heard others parrot the phrase "comments are a code smell".  I certainly didn't come up with it and can claim no credit in its creation.  But I have come to (almost always) agree with it.  And the reason I agree with it really speaks to much deeper ideals about _how to code_.
<br/><br/>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vmtrgl19jl682qkuko96.png)
## Programmer Evolution
Most of us have followed a similar path to "enlightenment".  It tends to look something like this:
<br/>

**1. Whatever Works**
This whole coding thing is brand new.  We don't really have any clue what we're doing.  We're usually baffled when our code doesn't work.  Even when it _does_ work, we're often somewhat confused about _why_ it works.  We have no experience with any aspects of "professional" software development.   

In this first stage of evolution, our code may look something like this:

```javascript
const currSC = () => {
  const db = connect('rt', 'kwqw92klad92;wqed');
  return db.get('amt').from('sc').where('sess = ' + sess.Id);
}

const st = (amt) => {
  return amt * 1.07;
} 

let tot = currSC();
tot = st(tot);
```

At this stage in our evolution, there is only one standard of "quality":  Does it _work_??  And if anyone tries to point out that some of this might be a _biiiiiit_ obtuse, their objections sound rather silly to us.  The code is clearly, _obviously_, self-explanatory.  So why would we waste time with silly comments??

Inevitably, we end up having to revisit _our own_ code.  It may be months later.  Heck, it may only be _weeks_ later.  But at some point, we're staring at _our own_ logic - and it no longer seems so... logical.  
<br/>

**2. Comments To The Rescue(?)**
This is when we first start getting some of that comment religion.  The abbreviations that felt so natural - only a short while ago - have now left our mind.  But there's a "fix" for this!  The how-to-code gurus tell us to "Use Comments!"  

Now that we've seen the downside of writing unintelligible code, the Copious Comment Strategy makes sooooo much more sense.  And all of the talking heads hail it as the mark of a good programmer.  So... we dive in.  Head friggin first.  And we typically end up with something like this:

```javascript
// gets the current shopping cart total, based on the user's session ID
// returns a number for the current total
const currSC = () => {
  // connect to database
  const db = connect('rt', 'kwqw92klad92;wqed');
  // find any saved shopping cart total in the 'amt' column in the 'sc' table based on session ID
  return db.get('amt').from('sc').where('sess = ' + sess.Id);
}

// calculate sales tax
const st = (amt) => {
  return amt * 1.07;
} 

// retrieve current total
let tot = currSC();
// add sales tax
tot = st(tot);
```

The pseudo-code above isn't... _wrong_.  I consider it to be somewhat _amateurish_.  And I wouldn't hire someone on _my_ team who wrote code like this.  But this approach is at least "functional".  

Writing "functional" code is certainly not a bad thing.  The _bad_ thing is that far too many programmers reach this second stage of evolution - and they just _stop_.  

Seriously. 

If you never evolve past step 1, you'll probably never get hired to do software development.  But I've met plenty of guys who've been in this game for many years - and yet, they've never advanced past this level of evolution.
<br/>

**3. Removing The Translator**
The problem here is that farrrrr too many coders come to lean on their comments as though they are "translators".  The thinking goes like this:
<br/>

1. The code I've written is hard to understand.
2. So I'll add a bunch of comments to "translate" the code for anyone who reads the code after me.

<br/>I sincerely hope you recognize the horrific flaw in that logic.  Despite the connotation of the word "code", the simple fact is that most algorithms needn't be ridiculously difficult to understand.  

My girlfriend is incredibly intelligent.  But she's never been, nor has she ever tried to be, a programmer.  Despite this "difference" between us, there are times when I'm aggravated about a particular issue that I'm trying to solve in my code, and she ask asks me what's wrong.  So... I _show_ her the code.

And here's the thing:  When she looks at my code, she generally understands the underlying concept that I'm trying to solve/accomplish/develop.  Even though she's never coded a day in her life.  Sure, she doesn't know all the specifics of the language constructs I'm using.  But at a high level, she can actually _read_ my code - without actually being a coder at all.

Let me be perfectly clear with this.  You might be thinking:
<br/>

> Your non-programmer girlfriend understands your code because _comments_ are written in plain language and can be understood by nearly anyone!

<br/>Umm... _no_.  Absolutely not.  I rarely use comments.  I might have a _few_ lines of comments in a few _thousand_ lines of code.  So the fact that she can grasp the workings of my code has nothing to do with comments.  It has everything to do with the _way_ that I write my code.

The more "evolved" we become, the more attuned we become to the idea of _self-documenting_ code.  I can lay no claim to this concept.  It's been floating around programming circles for decades.  But even now, in the 2020s, I feel that far too many devs have a poor grasp of this concept.  

Think of it like this:  If I move to your town and I plan to work in your office for a long time to come, and if I speak English but everyone in your office speaks Russian, should I write all my emails in English and then try to add a whole pile of "translation" notes to every message?  Or should I just put in the effort to format the message, originally, in a way that anyone after me is likely to understand it?  In other words, should I keep blathering in English and lean on some "translator" to make everyone else understand?  Or should I make every effort to start writing my messages in Russian??

We can illustrate some of these translation roadblocks.  The pseudo-code above has some glaring issues:
<br/>

1. Cryptic abbreviations
1. Obtuse function names
1. Magic literals

<br/>So if we're going to address those issues in the name of self-documenting code, we could do something like this:

```javascript
// gets the current shopping cart total, based on the user's session ID
// returns a number for the current total
const getTotalFromShoppingCart = () => {
  // connect to database
  const database = connect(process.env.databaseUser, process.env.databasePassword);
  // find any saved shopping cart total in the 'amt' column in the 'sc' table based on session ID
  return database.get('amount').from('shoppingcarts').where('sessionid = ' + session.Id);
}

// calculate sales tax
const calculateSalesTax = (amount) => {
  return amount * salesTax.florida;
} 

// retrieve current total
const currentTotalInShoppingCart = getTotalFromShoppingCart();
// add sales tax
const currentTotalWithTax = calculateSalesTax(currentTotalInShoppingCart);
```

This is typically where _many_ devs - even seasoned, experienced devs - look at my code and think:
<br/>

> OMG!  Your variables are so longggg!  Everything's so verbose!  There's no way that I want to code like this!

<br/>But "long" is a relative term.  Yes, I tend to favor full-word-name variables.  And no, I don't necessarily expect you to do the same.  But I _do_ expect you to write your code in such a way that it's as self-explanatory _as it can be_.

In the example above, it's true that I've written some long variable names.  And some long function names.  But I've also written code that is, IMHO, fairly _self-explanatory_.  You can just... _read_ it.  In fact, it's so self-explanatory that the comments now seem rather... _silly_.  They just duplicate what you should already be able to understand _just by reading the code_.  

So if we're really going to turn this into some "level 3" code, there's really no need for _any_ of those comments.  This means that, even though my code might feel a little "heavier" as you read through the variable names, this "weight" is counterbalanced by the fact that I don't have to chuck everything full of comments in order for you to understand it.  This is illustrated by the readable nature of this:

```javascript
const getTotalFromShoppingCart = () => {
  const database = connect(process.env.databaseUser, process.env.databasePassword);
  return database.get('amount').from('shoppingcarts').where('sessionid = ' + session.Id);
}

const calculateSalesTax = (amount) => {
  return amount * salesTax.florida;
} 

const currentTotalInShoppingCart = getTotalFromShoppingCart();
const currentTotalWithTax = calculateSalesTax(currentTotalInShoppingCart);
```

This is why I feel, very strongly, that comments are, in general, a "code smell".  Because nearly all comments that I encounter are trying to explain to me _what the code is doing_.
<br/>

> **I shouldn't have to read any comments to understand what your code is _doing_.  I should be able to understand what your code is doing... _by reading the code_.**

<br/>I'm sorry (not sorry) if this sounds a bit harsh.  But if I have to read your comments to properly _grok_ your code - then... you've probably written some pretty crappy code.  Don't write esoteric code and then rely on your comments to tie it all together.  Just write some clearer damn code.
<br/><br/>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/yziacprrq4zkt9j19gob.jpg)
## When To Comment
At this point, you may be thinking that I demonize _all_ comments.  But that's not the case.  There _is_ a time and a place to use comments.  But like Regular Expressions, comments should be used as a _targeted_ tool.  They're powerful, when used properly.  But they can also be a sign of something truly _wrong_ in the code.

Here are a few examples where comments don't suck:
<br/>

**IDE Tooling (e.g., JSDoc)**
In modern coding environments, there are many instances where the comments aren't designed so much to speak to other _coders_.  Instead, they're written to speak _to the IDE_.  In other words, comments can help our development tools to "hook everything up" and check the data relationships as we code.  That would typically look something like this:

```javascript
/**
 * @returns {number}
 */
const getTotalFromShoppingCart = () => {
   const database = connect(process.env.databaseUser, process.env.databasePassword);
   return database.get('amount').from('shoppingcarts').where('sessionid = ' + session.Id);
}

/**
 * @param {number} amount
 * @returns {number}
 */
const calculateSalesTax = (amount) => {
   return amount * salesTax.florida;
}

const currentTotalInShoppingCart = getTotalFromShoppingCart();
const currentTotalWithTax = calculateSalesTax(currentTotalInShoppingCart);
```

I'm not always the biggest fan of JSDoc.  But I don't generally have any problem with its use.  And I understand the service it provides.  So if _this_ is how you're using comments, then... great.  As long as this is the approach embraced by your team, then it's certainly a valid use of comments.

[Side Note:  Don't be _that guy_ - the one who insists on cramming JSDoc notation into all of his code files, even though the rest of the team has consciously eschewed it.  Conversely, don't be _that guy_ that refuses to add JSDoc comment blocks to his functions when the rest of the team has settled on it as a standard.]
<br/>

**Not _What_, But _Why_**
As I've already tried to explain, if your comments tell me _what_ your code is doing, then it's probably some crappy code.  But there's a very different use-case to consider:  Sometimes, we need to alert others as to _why_ our code is doing what it's doing.  

For example, consider the little pseudo-app we've been working with up to this point.  Even after we've made things as "clear" as possible with expressive variable/function names, it can still sometimes be a challenge to understand _why_ the code is doing what it's doing.  Specifically, let's look at this function:

```javascript
const calculateSalesTax = (amount) => {
  return amount * salesTax.florida;
} 
```

Seems pretty simple, right?  It accepts a given `amount` and returns that `amount` multiplied by _Florida's_ sales tax.  But for a sharp coder, this begs a question:
<br/>

> Why have we hardcoded a sales tax number that is only specific _to Florida_???

<br/>If you're accustomed to building hardy, scaleable apps, this bit of hardcoded logic seems... _off_.  In fact, it's the kind of "oversight" that might lead me to spontaneously refactor the code to utilize a `lookupSalesTaxRate()` function - even if my current task didn't call for it.  This is where a well-placed comment can do a world of good:

```javascript
const calculateSalesTax = (amount) => {
  // The client specifically told us that they only operate in Florida and they have no plans
  // for expansion.  They understand that we will need to rework this if they ever decide 
  // to do commerce outside the state of Florida.
  return amount * salesTax.florida;
} 
```

IMHO, this is an excellent use of a comment.  It basically alerts all future coders that the current logic is not an oversight and should not be changed, unless that change is driven by the client.  

To put this in different terms, we can already tell, by simply reading the code, _what_ it's doing.  But it's not clear, from the code, exactly _why_ it's doing that.  In this case, the comment can be extremely useful.
<br/><br/>

##Conclusion
Last year, I worked in a shop that had PHP code like this:

```php
//foreach
foreach ($items as $index => $item) {

}
```

I wish I was making that up, but I'm not even kidding.  They had comments _above basic language constructs_, ostensibly to alert you to the fact that those basic language constructs were there.  It was no different than putting a `STOP AHEAD` sign one meter in front of the `STOP` sign.  It was one of the dumbest damn things I've _ever_ seen in a codebase (and that's saying _a lot_).  

Don't be "that guy".  Be smart about how you use your comments.  And, more often than not... don't use them.  _At all._