Beginning in Scala and reading about Either
I naturally comparing new concepts to something I know (in this case from Java). Are there any differences from the
Either is equivalent to a checked exception in terms of the return signature forming an exclusive disjunction. The result can be a thrown exception X or an A. However, throwing an exception isn't equivalent to returning one – the first is not referentially transparent.
Where Scala's Either is not (as of 2.9) equivalent is that a return type is positively biased, and requires effort to extract/deconstruct the Exception, Either is unbiased; you need to explicitly ask for the left or right value. This is a topic of some discussion, and in practice a bit of pain – consider the following three calls to Either producing methods
for {
a <- eitherA("input").right
b <- eitherB(a).right
c <- eitherC(b).right
} yield c // Either[Exception, C]
you need to manually thread through the RHS. This may not seem that onerous, but in practice is a pain and somewhat surprising to new-comers.
Yes, Either
is a way to embed exceptions in a language; where a set of operations that can fail can throw an error value to some non-local site.
In addition to the practical issues Rex mentioned, there's some extra things you get from the simple semantics of an Either
:
Either
forms a monad; so you can use monadic operations over sets of expressions that evaluate to Either
. E.g. for short circuiting evaluation without having to test the result Either
is in the type -- so the type checker alone is sufficient to track incorrect handling of the valueOnce you have the ability to return either an error message (Left s)
or a successful value Right v
, you can layer exceptions on top, as just Either
plus an error handler, as is done for MonadError in Haskell.
Either
can be used for more than just exceptions. For example, if you were to have a user either type input for you or specify a file containing that input, you could represent that as Either[String, File]
.
Either
is very often used for exception handling. The main difference between Either
and checked exceptions is that control flow with Either
is always explicit. The compiler really won't let you forget that you are dealing with an Either
; it won't collect Either
s from multiple places without you being aware of it, everything that is returned must be an Either
, etc.. Because of this, you use Either
not when maybe something extraordinary will go wrong, but as a normal part of controlling program execution. Also, Either
does not capture a stack trace, making it much more efficient than a typical exception.
One other difference is that exceptions can be used for control flow. Need to jump out of three nested loops? No problem--throw an exception (without a stack trace) and catch it on the outside. Need to jump out of five nested method calls? No problem! Either doesn't supply anything like this.
That said, as you've pointed out there are a number of similarities. You can pass back information (though Either
makes that trivial, while checked exceptions make you write your own class to store any extra information you want); you can pass the Either
on or you can fold it into something else, etc..
So, in summary: although you can accomplish the same things with Either
and checked exceptions with regards to explicit error handling, they are relatively different in practice. In particular, Either
makes creating and passing back different states really easy, while checked exceptions are good at bypassing all your normal control flow to get back, hopefully, to somewhere that an extraordinary condition can be sensibly dealt with.