prose :: and :: conz

Option[T] > null

I was talking to one of my co-ops today about what an Option in Scala is, and it reminded me that I’ve been meaning to blog about option types. Plus Mom has been bugging me for another good coding blog post since I’ve been a little quiet lately. I’ve just been having too much fun writing SNMP4S which no one, I mean NO ONE, not even Mom, will ever use.

So what is Option[T]? There are several ways to think of it. One way is to consider it a Collection[T] just like Set[T] or List[T] but with size/cardinality 0 or 1. That is, it is either empty, or full. You can iterate over it (either zero iterations or one iteration), map over it, reduce it, etc. It is implemented with a small hierarchy of classes. If it is empty, then it is a None. If it is not empty/full, it is a Some[T]. You can certainly see that Option[T] is an abstract base class and None and Some[T] are the only two concrete sub-classes.

Okay… why? The idea is you want expose fields, arguments, etc as not being required and hence optional. My initial thought is that it’s no better than what Java already provides with null. That is, you have the object or you have null. Now instead of this code:

String str = map.get("key");
if(str != null)

I now have this code:

val str:Option[String] = map get "key"

It’s basically the same amount of code. It also doesn’t eliminate the possibility of getting a runtime exception. Just as dereferencing null produces a NullPointerException, calling get() on a None throws a NoSuchElementException. I just thought they were taking the null pointer problem and moving it, hence not avoiding Tony Hoare’s “billion-dollar mistake”. I’d love to see languages disallow null pointers altogether, but this wasn’t solving that problem in my mind.

But, I wouldn’t be writing this post had I not seen that Option[T] is FAR superior to using null. How so? Well consider the differences in signature for Map[K, V].get(key:K) between Java and Scala:

V get(Object key)
get(key: K): Option[V]

Without looking at the documentation, which of these two might return a null or None? Yeah, the Scala one. The Option type is a big red flag that says “This thing possibly has an undefined value, so you better handle that.” Don’t get me wrong, they both say that in the respective docs:

<Java>Returns: the value to which the specified key is mapped, or null if this map contains no mapping for the key

<Scala>Returns: an option value containing the value associated with key in this map, or None if none exists.

The explicit declaration that a type could be undefined is a fantastic idea. The caller of the API is explicitly warned in the code that None is a distinct possibility and any calls that just return T are guaranteed to be legit instances of T (WARNING: Not true for Scala, unfortunately. In order to interop with Java libraries, Scala also has a null. If only Java had gone the option route!). Hence it’s not even possible for the call to return something dereferenceable unless the creator of the API explicitly advertised that possibility. It does in fact just move the null reference problem, but it moves it to the type system which I’m finding more and more is a good idea.

Tagged with: scala (41), functional-programming (31)