Saturday, February 8, 2014

The Best Programming Language


This post is not about Java vs .Net or Python vs Ruby or any other programming language in particular. This post is about the programming language that is common to all of them. We call these technologies languages but in fact all of them are written in English (well aside for a few). But unlike English article or blog post, programs are often very hard to read. In this post I want to share with you how I try to keep my code readable and maintainable.


Inflation of comments


When I started to program professionally, more than ten years ago, I felt it was pretty hard for me to get into others' code. I was having a hard time reading it. I wanted to make sure my code wouldn't look like that. So, as we often do, I made sure my code was filled with tons of comments. Let me demonstrate with an example (code taken from my refactoring hands-on post, comments added for this post):


That's not the whole class but it pretty much reflects the idea. Now, take a second and try to figure out what this code does more or less.

I bet you didn't read the comments. And if you did, that's only because I have been writing about comments from the beginning of this section. Most of the times we are blind to comments, we ignore them. Especially if there are many of them and we're already used to them stating the obvious. Do I really need a comment stating that this is THE item Dao?



All of the comments in this code are pretty much the same, stating the obvious. This is not readable code, this is cluttered code that needs to be maintained twice - once for the code itself and once for the comments. Problem is - comments tend to rot. We don't have to maintain them, the computer doesn't care what they say, the computer only cares about the code. So, we tend to neglect them. I bet most of you didn't even find the copy-paste mistake hidden in the comments.



Deflation of comments


After I realized that I was inflating comments, I started to deflate them. I wanted my code to feel that when there's a comment, it must be read, it's important. I eliminated all of, what I call, "The Duh" comments.



I only added comments when I really needed to explain what I was doing. For example, what I like to call "The eeeefff if" (because it's such a code-smell):


No way you can understand what this if-clause checks on the first read. You'll have to read it at least twice, and usually 3-4-5 times, to be certain you understand the code. In this kind of scenarios I had usually put a comment that stated what this clause was supposed to do: "Checks if the document has a title or if we can extract a title" (for the sake of the example - let's assume we can extract a title from video/image). Ok, that's a bit clearer now, but we need to consider two things:
  1. People will still, most likely, try to read the code before the comment (assuming they won't ignore it completely).
  2. Even after reading the comment, it is still not clear why we are so certain we can extract a title. The if is complicated, and we can't be sure the comment is aligned with the code and hasn't rotten yet (at least without checking the source-control history).
We'll get back to this example later.


/* No comment */


At the last stage (so far...) in my journey for writing readable code I realized, with the help of Uncle Bob in his book Clean Code, that I should make my code readable without comments. This may sound extreme at first, "A code that is readable without any comments?", well... yes. Aside for some very specific cases, you should aspire to avoid comments in your code and just write code that is readable on its own.



Writing code in English


If you manage to write code with each line looking like a sentence in English, each method is a paragraph telling about a very specific subject of the big picture, and each class tells only one aspect of the story - you will not need almost any comments, and your code will be readable. And also as a beneficial side effect, well-designed and maintainable. Uncle Bob compares this type of code to a newspaper where you have articles (classes) with headers (high-level method abstraction), sub-headers and text which both represent different levels of implementation details.

The two main ways in my opinion to achieve such code are:

  1. Descriptive naming
  2. English-like sentences

Descriptive naming


There's just so much to say about descriptive naming which makes it a topic for another post. I'll just give a few pointers for good naming:

  • Give clear descriptive names which can be used in English-like sentences (will be described in the next paragraph)
  • Avoid using abbreviations
  • Stick to conventions
  • Avoid making the reader scroll up/down the page to figure out what a variable/method/class is meant for. With good naming, usually no scrolling will be needed.
Giving names to things is amongst the programmer's most difficult tasks. I suggest that when you write the code, start with any name (even foo for a method), and improve it as you go along (but before you commit or ask for review).


English like sentences


Try to maintain the reading flow of your code-lines. Make them look like English sentences. For example:



You can read the if sentence like an English sentence "if store has client - currentClient". That is far more readable than doing something like:




The same goes for the ugly "if" we saw before. We can extract it to a private method in the Document class that simplifies the question in a form of an English sentence "if doc has title":

The new if form

The Document object will encapsulate the answer to the question by calling two private methods that each simplifies another aspect of the question: 


Each part of the question is simplified in its own method


This way completely abstracts for the readers the question "has title?" and its two sub-questions - "already has a title?" or "can a title be extracted?" The proximity of the methods in the code also counts, but I won't get into that in this post.



Is it ever ok to use comments?


Of course! Comments are needed for java docs, they are needed to explain a nasty hack, explain why you preferred one algorithm over the other (when it's not obvious) or add a TODO comment (but if it stays there for more than a few days - it's also a code-smell). Also, each rule has its exception and sometimes comments may be needed to explain the code. But try to make it the exception, and not the norm, to use comments to explain yourself.


Further Reading


This post was longer than most of my posts and I haven't even started to scratch the tip of the iceberg on the subject. I invite you to read Uncle Bob's Clean Code in order to improve your code-writing skills. Also, don't hesitate to contact me (via Twitter, Linked-in or just leave a comment here) for more help on the subject.

I also invite you to send me code examples with explanation comments (even if we don't know each other yet) and we'll try to figure out together how to remove them and create a clean, readable code instead.



Find me on Twitter: @AviEtzioni



More interesting posts from this blog:

6 comments:

  1. Some people criticize uncle bob for over simplifying methods see this
    http://vimeo.com/49484333

    P.S
    I don't necessary agree with her but sometime creating a method with one line is too much

    ReplyDelete
  2. Thanks for the link - very interesting. And, of course, I'm no stranger to criticism to Uncle Bob's over-simplification.

    I think everything should be done with good taste. I did agree with her when she said that hiding s**t inside a method name is nasty. Instead - refactor to make it look better and designed better.

    Also - if you're keeping your classes small (I rarely hit the 200 hundred lines when I write a completely new code) you get very small and testable units. In such small classes, you don't have to over simplify because there's so little going on. That's another aspect of readability I think. But this blog is too short to write a new "Clean Code" so I just gave a taste of what I think :)

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Great post Avi, thanks!
    :)
    For the sake of accuracy, I would suggest to change && to || in Document.canExctractTitle().

    ReplyDelete
    Replies
    1. Thanks for your reply. But look again at the original demonstration - it contains 2 AND conditions (each with parentheses) that are combined with an OR condition. I extracted each AND condition to its own method and a 3rd method calls the 2 AND methods with an OR. So, we're good :)

      Delete