Null Values

Earlier I complained about the fact that function parameters are never constant by default. I do not know of any non-functional language that hasn’t made this mistake (this of course not being an issue in a functional language since everything is a value — immutable.)

Another common decision that I think is even worse, and might be the worst feature of these languages is null. null is treated as an object by the compilers/interpreters, but the programmer can not treat it as such.

This means that anywhere you can put an object, you may also put null. Car myCar = null; is perfectly valid Java, and even myCar.getManufacturer(); will compile. You will then have to wait until the actual code runs in order to get a NullPointerException. What this means in practice is that any time you’re not 100% sure that a value cannot possibly be null, you have to perform a myCar == null check to avoid these errors. Of course, you’ll want to avoid null values as often as possible for this reason. There is also the notion of Null Object in OOP languages, an object that also means “no value”, but it’s a real object meaning myCar.getManufacturer(); will in fact work, albeit it might return “N/A” instead, a procedure will simply do nothing when operating on null objects.

It quickly becomes hard to know where you will need these null checks and where null objects are available. Can you really trust documentation to give you all the information you need? If you assume that a value can’t be null because the docs don’t say they can, you will probably run into trouble. If you assume they can be null, you will have to write so many null checks your hands will call it quits.

Objective-C has an interesting (albeit in my opinion terrible) way of treating null values; pass a message to a null value, and no method executes, null is simply returned again. This allows for chains like [[[[a b] c] d] e] returning null, instead of operations being performed. Then you of course have to figure out where in the chain the null value popped up.

Haskell has solved this in what i find to be an elegant manner. For instance, the function lookup (that tries to find a certain value in an association list) has the type signature Eq a => a -> [(a, b)] -> Maybe b.

If you do not know Haskell, this type signature can be explained as “A function taking a key a to look up in an association list [(a, b)] (a list of key/value pairs) and then returns a value of type Maybe b where b is the value of such a list. An association list in Haskell is not a distinct data type, it’s just by convention a list of tuples, but that’s another subject.

Maybe b is a type that has two constructors, either Just b or Nothing. Nothing means that no value exists, or in this instance that no key/value pair with the given key existed. Just b means that a value b exists (was found).

The alternative in other languages would be to either return null when no value was found, or to throw an exception.

I recently found the reason that null came into existence, first invented and implemented by Tony Hoare (Inventor of QuickSort, Turing Award winner) back in 1965 for the OO language Algol W. The reason it was added? It was easy to implement! Tony Hoare has realized how huge of a mistake this was.

Unfortunately designers of new languages seem to mostly mimic what’s already been done. Sure, changing something everybody expects (the ability to specify values as null) can be a hit or miss in the software engineering community where, theoretical upsides are seldom a deciding factor. My software engineering professor stated this fact quite bluntly by saying “In SE; if it seems to work, we use it.”

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]".

More information about formatting options