May be my design is flawed (most probably it is) but I have been thinking about the way Option
is used in Scala
and I am not so very happy about it. Let's say I have 3 methods calling one another like this:
def A(): reads a file and returns something
def B(): returns something
def C(): Side effect (writes into DB)
and C()
calls B()
and in turn B()
calls A()
Now, as A() is dependent on I/O
ops, I had to handle the exceptions and return and Option
otherwise it won't compile (if A()
does not return anything). As B()
receives an Option
from A()
and it has to return something, it is bound to return another Option
to C()
. So, you can possibly imagine that my code is flooded with match/case Some/case None
(don't have the liberty to use getOrElse()
always). And, if C()
is dependent on some other methods which also return Option
, you would be scared to look at the definition of C()
.
So, am I missing something? Or how flawed is my design? How can I improve it?
am I missing something?
Option
is one design decision, but there can be others. I.e what happens when you want to describe the error returned by the API? Option
can only tell you two kinds of state, either I have successfully read a value, or I failed. But sometimes you really want to know why you failed. Or more so, If I return None
, is it because the file isn't there or because I failed on an exception (i.e. I don't have permission to read the file?).
Whichever path you choose, you'll usually be dealing with one or more effects. Option
is one such effect which representing a partial function, i.e. this operation may not yield a result. While using pattern matching with Option
, as other said, is one way of handling it, there are other operations which decrease the verbosity.
For example, if you want to invoke an operation in case the value exists and another in case it isn't and they both have the same return type, you can use Option.fold
:
scala> val maybeValue = Some(1)
maybeValue: Some[Int] = Some(1)
scala> maybeValue.fold(0)(x => x + 1)
res0: Int = 2
Generally, there are many such combinators defined on Option
and other effects, and they might seem cumbersome at the beginning, later they come to grow on you and you see their real power when you want to compose operations one after the other.