Avoid null: Use an Optional type instead

Did you know that “null” is a concept that had to be invented?   C.A.R. Hoare created it in 1965 as part of the Algol W language.  I think adding “null” to programming languages was a giant step in the wrong direction.  But you don’t have to take my word for it.  C.A.R. Hoare agrees with me and calls it his Billion Dollar Mistake. Since “null” had to be invented and Algol W wasn’t the first programming language, that means that there must be programming languages without the concept of “null”.  

But, how do they avoid this?  For example, what if you get some data from a database and the row is not there?  If a language doesn’t have “null”, how could it represent this state?  The answer is with the Optional type. In this article I’m going to explain in detail why you should prefer the Optional type (AKA the Maybe type) over “null”. But before I explain this, I want to explain what I dislike about “null”.

“Null” is not that big of an issue if you read and write all the code you use.  But as soon as you have to work with someone else’s code, it starts slowing you down in minor ways.  For example, if my programming language allows “null” and I write this code  var x = someLibrary.someMethod(y);, there is a lot of ambiguity.  When “null” is a possibility, this single line makes me wonder 3 things:

  1. Is someLibrary  “null”?
  2. Can I pass in “null” for y ?
  3. Is x “null” because  someMethod can return “null”?

It is inconvenient (relative to the alternative I will explain below) to answer these questions.  The only way I know how is to “read documentation”/”trial and error at run time”/”assume”/”guess”.  There’s something unsatisfying about each of these options. If I make the wrong assumption, it may take a very long time for me to realize my mistake.  I’ll only see the problem if I run this code (because the error only happens at run time), at that point I’ll have to recompile and redeploy to fix the issue.  

Worst case scenario, these issues can take down a production environment.  And if one line of code can give me 3 areas of concern, imagine how this adds up in projects that have thousands of lines of code.  A minor inconvenience multiplied a thousand times can turn into a major liability. Wouldn’t it be better if there was a way to prevent these errors and catch them at compile time?  Wouldn’t it be better if the code told me if Step 1, 2, or 3 was “yes” or “no”?  Optional types give a means to do this. The Optional type works like this (this is Java code, but the concept applies to all languages):

As you can see, one advantage to using Optional is that the code becomes self documenting.  You don’t have to guess whether code accepts or returns “null” because it tells you.  This is a huge advantage in maintainability.  Another advantage is that you have to write optional.get() to get the value out of it.  That means you can’t accidentally overlook that the value is missing.

I’m not going to pretend this is 100% win with no downside.  As you can see with the maybeFoo  field above, our code has to deal with the possibility that it may be empty even though we know that it’s not.  In other words, Optional forces you to deal with missing values even if you know they’re there, but null lets you use missing values even when you shouldn’t.  In my opinion, the way that Optional is self documenting and finds issues at compile time makes it a better choice than “null”.

By the way, you can find the source code of this example here: https://github.com/tieTYT/OptionalCookbook

Join the email list for bonus content.

Leave a Reply

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