In "Offense" of Scala's Option class; a guarded defense of Cédric's rant
July 30, 2010 📬 Get My Weekly Newsletter ☞
In a recent blog entry, Cédric Beust calls out scala’s Option
class as nothing more significant than null checks. Commenters rightly set him straight that the thesis of his blog post was marred by an ignorance of idiomatic use of the class.
But, it’s hard to really blame Cédric, when you look at what he had to go on. Odersky’s book states that one should use pattern matching with Option
, and the scaladoc for Option is just abysmal:
This class represents optional values. Instances of Option are either instances of case class Some or it is case object None.
That is the entire description of the class, no examples, nothing. Worse, the method that commenters called out as idiomatic, flatMap
, has the following description:
If the option is nonempty, return a function applied to its value. Otherwise return None.
This is not what Option#flatMap
actually appears to do (nor is documented to do; it’s documented to return an Option[B]
!):
It certainly doesn’t call itself out as “the way” to use Option. A simple example in the scaladoc could have gone a long way.
So, angry post + helpful commenters == problem solved, right?
Wrong.
The Option
class is, really, an implementation of the NullObject pattern, and a more elegant way to handle optional values. In scala, we might have this method signature:
This means “update my name; lastName is required and firstName is optional”. In java, this method might look like this:
So, what’s the right way to do it in Scala? According to the commentors:
Yech. Does anyone else think that calling a method called “foreach” on our “optional value” is just nonsensical? Or that the idiomatic way to treat an optional value is as a collection, e.g. by using the for
comprehension? This just feels hacky. Naming is one of the most important (and challenging) things in software engineering, and Option
’s API is an utter failure (even its name is wrong; when one has an option, one typicaly has many choices, not just one or nothing. Optional is really what is meant here, so why are we afraid of adding a few more letters? Especially given how “precise” some of the documentation is, mathematically speaking, why are we not being precise with English?). If Option
is just shorthand for a “list of zero or one elements”, and we get no better methods than what comes with List
, then what’s even the point of the class?
I’m not saying we remove all the collection methods from Option
, but how about a throwing us a bone to make our code readable and learnable without running to the scaladoc (or REPL) to see what’s going on? I mean, there’s a method on Option
called withFilter
whose documented purpose (I’m not making this up) is: “Necessary to keep Option from being implicitly converted to Iterable in for comprehensions”. Am I expected to believe that it’s ok to have this hacky pile of cruft, but we can’t get a readable method for “do something to the contents if they are there”?
Which would be less surprising? Couple this with some better scaladoc:
With these examples, you cover the two main uses of this class, show newcomers how to use it, and demonstrate its superiority over null checks.
It’s frustrating to see this, because Scala has so much potential to be a lucid, accessible, readable language, but API usability and learnability are just not prioties. Scala needs to take some lessons from Ruby in terms of API design (and Java in terms of API documentation).
Of course, none of this does save you from null, because Scala is perfectly happy to assign null to anything. It kinda makes the whole thing seem a bit pointless.