I was doing some research on a topic about compulsory parameters to constuctors for a project I was doing when I came across a topic about the use of NULL as a return value. Don’t ask me how I stumble into these things. As you can imagine, as with everything in software engineering circles, there was a raging debate about whether or not NULL (or its equivalents like None in Python) was an acceptable return value. In this article I am going to express my opinion on why NULL is perfectly acceptable, but only in certain circumstances. I am also going to show why the “special case pattern” outlined by Martin Fowler is just a bad idea for large scale applications and perhaps even some smaller ones. Yes I know, I am going to make a case against a Martin Fowler concept. Let’s dive in!
To best answer the question, let’s fall back on what we know in every day life and the expectations we have for interactions. I mean, we should be designing things with readability but also matches our ideas and concepts of the things we are trying to model in life. We will assume we are at a grocery store and we are on the hunt for a particular brand of cereal. I mean, when I was younger there was no replacement for Lucky Charms… ask any kid if you don’t believe me. If I go into the grocery store and can’t find the Lucky Charms on the shelf, I would go to a store employee and ask “Do you carry any Lucky Charms cereal?” He might look at me funny given my age but never mind that part. What would my expectations be for his response? He might say “Yes, we have it right here.” He would then hand me a box. The other option would be “No, we don’t have it in stock. Sorry.” and I would be left with nothing.
Did you catch the subtle hint? You are left with NOTHING. You expected to be handed an object, a box of cereal, but you got nothing. You were not told “false”, you were not told “-1”, you were not told “here is this box called missing Lucky Charms cereal”. You get nothing! This is important. It is not what we want in some cases, but that is life.
It is acceptable to return NULL (programming speak form of “nothing”, “the lack of anything”, “the void”) if you expect to be getting an object and it is just not there. Now if there was an error finding it, sure throw an exception or whatever. If it is just not there, you get nothing.
Yes this means you have to check if you received nothing before you can work with what you got. Yes it might be a bit more tedious or repetitive that you have to check if you got something, but if you expected to get something and you didn’t then that is what you have to work with. If you are smart, perhaps check once you didn’t get something and remember it some how rather than checking a million times.
Now I am not saying returning NULL is universal to all functions. If you expect to get a string, returning an empty string might be acceptable. If you are expecting an integer and returning an invalid integer might also be acceptable. Perhaps you are expecting a number between 0 and 100 where you return 0 as being the closest value to -1 that too might be acceptable. What I am saying here with NULL applies mostly to objects. If I expect a concrete object to work with, I expect that or nothing. Don’t hand me something as a proxy or hand me something that is not what I am expecting. Don’t hand me any old box of generic cereal to say we didn’t find your cereal, but take this to work with. Most cases I am just going to throw it away once I realize I didn’t get what I was looking for.
Now for the heresy. In the article I stumbled across, one poster referred to Special Case Pattern which explains returning a class with the same interface as what is expected to be returned to avoid having to check for NULL, or preventing NULL exceptions (trying to use a class that is null). There are some fundamental problems with this approach…
Sometimes I think we get into our own heads a bit too much when it comes to what we are trying to communicate with our software designs. We make elaborate setups to avoid simple rules of our own understanding. We are in the middle of the isle of our grocery store with either a box of Lucky Charms in our hand or we are not. We don’t have fake boxes of cereal, we don’t have a boolean value of false, we don’t have a hair dryer as our closest “proxy” to what we asked for. We just don’t have anything! NULL, I think, adequately describes our expectations of having an object or not. Don’t over complicate things.
If you liked this article and want to practice what you have learned, be sure to check out my project ebook titled “The Programmers Idea Book – 200 Software Project Ideas And Tips To Developing Them“. In the book you can get a ton of project ideas, some small, some larger, all language neutral (can be written in your language of choice).
Thanks for reading! 🙂