DEV Community

Cover image for Don't write code for computers
James Wade
James Wade

Posted on

Don't write code for computers

When trying to keep code simple, you may find yourself torn as to what is more simple, less code or more verbose code?

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand” - Martin Fowler

The problem

Often we attempt to be explicit by adding more documentation or comments, however this doesn’t always end up the way we hope. The comments end up implying what the code will do, rather than the code being self documenting and explicit.

“Redundant comments are just places to collect lies and misinformation.” ― Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship

Comments become redundant because they often differ from the code itself, especially over time. The more complex the code, often the more comments there are and the more it is likely to differ over time.

You have to put yourself in the shoes of the next person to read your code. They are unlikely to read your comment, less understand it, so will simply read what the code is doing instead and then change the code to whatever they need it to do, without updating the comments.

Docblocks are different to comments and often a place to put annotations, but even those where possible are favourable to put into the actual language, than in the docblock. Although docblocks can be used to describe methods, they shouldn’t describe the logic itself, the code should do that.

The solution

Rather than writing comments, see if you can refactor the code to make it more obvious. Break out complex logic into a new method. Use variable names to give context to its value. Avoid magic numbers and strings, instead use well defined constants.

It may not feel like writing mode code is the most pragmatic approach as you will write more code, however it will save you time in the long run and you won't need to refactor as much.

When you're explicit upfront, you'll find it much easier to write tests, debug and ultimately maintain rather than an implicit approach which leads to ambiguity and uncertainty.

“When you feel the need to write a comment, first try to refactor the code so that any comment becomes superfluous” - Martin Fowler

If you find yourself in a situation where you can choose whether to go with strict typing, you should because it means you can be explicit.

In 1974, Liskov and Zilles defined a strongly-typed language as one in which "whenever an object is passed from a calling function to a called function, its type must be compatible with the type declared in the called function."

Being explicit also puts less burden on the resources as it doesn't have to guess what you mean.

Similarly to keeping it simple, when you're thinking “clever” or “smart” by using implicit methods, see if you can opt for idiot proof and explicit method instead.

First, if the code is clear, and uses good type names and variable names, it should explain itself. Second, comments aren't checked by the compiler, so there is no guarantee they're right, especially after the code is modified. A misleading comment can be very confusing. Third, the issue of typography: comments clutter code. - Rob Pike, February 21, 1989

It's good to be explicit when it comes to standards too. Having implicit standards will soon get lost as new people begin to put their own spin on the code. That's why it's best to choose and define the coding standards and stick to that. It will save a lot of time.

Have you had experience with comments vs code? Do you have any examples? I'd love to hear about them in the comments.

Top comments (1)

Collapse
 
tandrieu profile image
Thibaut Andrieu

I have never seen a code that was too much documented, neither did I already spend time because of obsolete comments. But I DO already have spent time because I didn't understand the logic behind a line of code.

Real example that happened to me yesterday when working on a Qt application:

void Item::setEnable(bool isEnable)
{
  if ( isEnable != m_isEnable )
    prepareGeometryChange();

  m_isEnable = isEnable;
}
Enter fullscreen mode Exit fullscreen mode

Simple code, isn't it ? It may be obvious for some, but why do enabling or disabling an item would have an impact on its geometry ? Why prepareGeometryChange() instead of repaint(), redraw() or any paint method ? I spent 1 hour to figure out why replacing prepareGeometryChanged() by a repaint() didn't worked. And:

void Item::setEnable(bool isEnable)
{
  if ( isEnable != m_isEnable )
    // disabling item make it invisible, so its bbox should be empty.
    // We should notify Qt that Item's geometry has changed so it can update its bbox cache.
    prepareGeometryChange();

  m_isEnable = isEnable;
}
Enter fullscreen mode Exit fullscreen mode

I'm really skeptical about auto-commented code. Each time I've heard about it in my job, it was by developers that assume their code was just obvious to understand as is (spoiler: it wasn't...).

However, a good comment don't explain what a line do. That the purpose of good naming. It explains why this line is here. Why is it required whereas you did not expect it to be there.

Another example I had to face was usage of Double check locking. This pattern typically look like a copy/past issue:

parallel section
  if someCondition()
    lock()
      if someCondition()
        doSomething()
Enter fullscreen mode Exit fullscreen mode

At first, this look like a bug or a merge issue. You test the same condition twice and a developer that don't know this pattern would be tempted to remove the first check. The application will work correctly, but performances may be greatly impacted. But with a small comment:

parallel section
  // quick test without lock. See Double check locking (https://en.wikipedia.org/wiki/Double-checked_locking)
  if someCondition()
    lock()
      if someCondition()
        doSomething()
Enter fullscreen mode Exit fullscreen mode

Nothing more. Don't explain which condition you are checking, don't explain what happen. Just point that you are using a not well known pattern and that this line is expected here.

Comments don't replace good naming. But I don't think you can always replace a comment by good naming.

Btw, quotes of article are taken from the excellent book "Refactoring -
Improving the Design of Existing Code". A must read 😉