Tuesday, December 8, 2015

Scala: You have the Option to Try Either

Doesn't make sense, right? Well that's how the Scala types Option, Try or Either will seem like initially. They are an interesting way to solve the problem of returning values from methods. Lets look at each of them by way of examples.

Option

Lets say, you are writing a financial API system. And lets say you need to write a method that accepts a login and a security token and return a valid transaction handle to perform transactions, or an empty handle if either the login or security token are invalid. Then the method might look something like this.


The return type Option[TransactionHandle] above indicates that the method can return an instance of TransactionHandle or None. So here's how you might use the getTransactionHandle method:



Option is thus a wrapper type that encapsulates an instance of scala.Some or None (that's a little over-simplification - scala.Some is a subtype of Option and None is a subtype of Any). scala.Some in turn encapsulates an existing value of some type. Thus when a method returns an instance of Option[T], the returned value is either an instance of Some[T] or None. Option is Scala's way of avoiding the NPE (NullPointerException) surprises by explicitly informing that a method can return an empty value and allow the user to gracefully handle the situation. However more importantly, if the user fails to handle None - it will not cause an NPE. If you examine the Scala doc for Option, you will see that Option can be treated as a collection that has zero or one element. And that collection like treatment is valid whether the Option contains Some or None.


Try, Success Failure

Now lets look again at the getTransactionHandle method. It returns either a valid handle or None (null). We can rewrite that by using Try, Success and Failure as follows:


The return type Try[TransactionHandle] can be processed as follows:


Either Left or Right

Earlier we saw Option as a way to return None or Some. Either gives you the option (no pun intended) to return a value of one type or another. For example, the method below accepts a String and returns an instance of File if the String represents a valid file path or an array of String instances if the input String represents a valid directory, with the array being the contents of that directory. if the String represents a non-existent path, then the method returns None. Note that this is a very contrived example - an array would be sufficent to represent all three scenarios - a non-existent file, a file, and the contents of a directory. However in the simplistic case, an empty array due to a non-existent file v/s an empty array due to an empty directory would be non-distinguishable.


Why All This Fuss About Option, Either and Try?

First of all, the use of Option helps reduce (eliminate?) the dreaded NPEs (Null Pointer Exceptions). Instead of using a safety net of try-catch, you have a smooth logic flow of an if or getOrElse statement. And unlike a try-catch where the exception is handled only around the scope of the method call, using Option, one can examine the method result at various points in the code using their respective boolean methods. Below are the ways you can check for the alternate values from Option, Either and Try.

Option:   isDefined   or   isEmpty
Either:    isLeft         or   isRight
Try:        isSuccess    or   isFailure

Finally, just as you don't need to do "distracting exception handling" you can also seamlessly iterate through Option and Try using "foreach". So if the Option or Try values returned by a method had Some or Success instances, then the iteration would have one item processed, else none. 


No comments:

Post a Comment