Archive for November, 2007

It's okay to return null

This blog post called Returning None is evil caught my attention. In this article, the author (Marty Alchin) tries to explain why you should never return None (this is Python’s equivalent of None). Since he also takes this opportunity to take a few unnecessary potshots at Java, I thought I’d make a few comments.

Marty seems to be prone to exaggeration. For example, he states that NullPointerExceptions (or rather, their Python equivalent) are:

exceptionally hard to debug

It typically takes me less than a minute to find such errors. The first ten seconds are dedicated to jumping to the place where the exception occurred, and the remaining to finding where that value came from (usually instantaneous with Java IDE’s. Python doesn’t have those… pity).

Marty then continues by saying that returning a None value indicates that

an error occurred

Well, not always. For example, when you look up a key that doesn’t exist in a dictionary, is this an error? It seems very much part of the contract of the class to me. There are many, many other situations where the fact that a value cannot be returned is not an error (such as looking up a configuration preference). Throwing an exception in these cases is not just a waste, it complicates the caller code needlessly and it deceives future readers into thinking that something very wrong occurred.

If you’re using Python (which I hope you are), embrace exceptions.

Absolutely. And Java programmers embrace exceptions just as much as Python developers (I’d argue that Java’s exception system is more sophisticated since it allows for both checked and unchecked exceptions, but let’s not digress).

I hope I’ve made the point well enough without writing a song called Raise an Exception. Whatever you do, don’t return None unless None represents some usefulness to your code.

Well… so what do we do? Unfortunately, the article ends here. At least if you’re going to criticize, offer a few suggestions to remedy the problem, will you?

Here is a scoop: exception should only be thrown for exceptional situations. Not finding a configuration value is not exceptional. Not finding a word in a document is not exceptional: it can happen, it’s even expected to happen, and it’s perfectly okay if it does.

So, what are we supposed to do when the situation is not exceptional and that, according to Marty, we can’t return None either? His post is interestingly silent on this, so let me try to offer a suggestion.

There is a design pattern known as the Null Object, which also tries to minimize the number of NullPointerExceptions one can encounter in the code. The idea is that when you are tempted to return null, you return an empty object of the desired type. This saves the user from testing for null, but it’s also fraught with all kinds of problems that I won’t get into, so it’s hardly ever used.

My advice: there is nothing wrong with returning null/None. All you need to do when you’re wondering whether you should throw an exception instead of returning null is whether the current situation is an error or whether it is expected to happen.

Android

Yes, this is what I have been working on. In six days, we will tell you everything, we promise!

Software headaches

Every once in a while in your career, you encounter problems or concepts that blow your mind. Either because they are complex or just because they are just plain exotic. Here are a few I can remember over the past 30+ years that I have been in the software industry…

  • Assembly language. I encountered this for the first time on my Apple ][. After a year of learning some Applesoft Basic, I encountered a curious instruction that I had never seen before: CALL 768. When I ran it, it played some music. After weeks of research (this was in the early 80′s… no Internet nor even books), I managed to figure out that I needed to switch to the “monitor”, convert the address in hexadecimal ($300) and see the “listing” (basically opcodes). I was absolutey mystified. I couldn’t make sense of any of this and but I did manage to alter the pitch and tune by inserting values in random places. It took me years to finally get a grasp of what’s going on. One thing for certain: I was hooked.

  • fork(). I encountered this mysterious function in my early CS classes, and if you’re not familiar with UNIX, it basically lets you spawn a new process. The semantics of this function is absolutely baffling, I just can’t understand how anyone could ever come up with this and think it’s intuitive. But as years go by, you just get used to it, just like you stop noticing this eyesore building every morning on your way to work.

  • Pointers. Aaah… pointers. Just when you think you start having a handle on this programming thing, a mean teacher throws you a curve ball and tries to explain to you how pointers work in Pascal. How inhuman. I suffered months of mental anguish trying to wrap my head around this concept, and then suddenly, it made sense (and I even managed to relate this to my earlier assembly language discoveries… now *that* was an epiphany).

  • Continuations. As opposed to the other three items described above, I can’t say that even as of today, I understand continuations. They just don’t make any sense to me and even if they did, I just can’t see any practical use to them except maybe to torture students and make sure you grade along the curve. Yuck.

    These are the main painful experiences I can remember, I’m sure there are more.

    How about you, readers: do you have any painful learning experiences to share in the area of computers?