Try vs Either in Scala 2.10

1,557 views
Skip to first unread message

Drew Kutcharian

unread,
Feb 12, 2013, 2:36:35 PM2/12/13
to scala...@googlegroups.com
Hi Guys,

When defining an API that could possibly throw an Exception, i.e.

getUser(id: Long): Option[User]

is it "better" to return a Try or an Either

getUser(id: Long): Either[Exception, Option[User]]

vs

getUser(id: Long): Try[Option[User]]

-- Drew

Rex Kerr

unread,
Feb 12, 2013, 3:09:28 PM2/12/13
to Drew Kutcharian, scala...@googlegroups.com
Personally I would use a Try (assuming None doesn't adequately convey the depth of failure of not getting that user).  I use Either when I want to pass back something specific to the error, and Try when it's just standard exception handling (which I want to have handled, but where I don't want to pass back any customized information).

Note that if you return Try, the custom is to write your code so it cannot throw an exception to escape the try.

def badForm(i: Int): Try[String] = {
  if (i<0) Try(myArray(i))       // This will surely fail
  else Success(myArray(i))  // But this will too if i is out of bounds!
}

Usually, the method will look something like

def foo = Try {
  blah.blah.blah
}

or

def foo = {
  Try(x).recover(bar).map(baz)
}

  --Rex


-- Drew

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



Pascal Voitot Dev

unread,
Feb 12, 2013, 3:34:17 PM2/12/13
to Rex Kerr, Drew Kutcharian, scala...@googlegroups.com
Either has a meaning of Either 1 or 2 and not only of Error/Success or Exception/Success.
Try has a meaning of try something and catch potential exception.
So in your case, Try seems to be more natural.

Regards
Pascal

Drew Kutcharian

unread,
Feb 12, 2013, 8:41:49 PM2/12/13
to scala-user@googlegroups.com User
I was leaning more towards Try too. I guess it's time to retire the the Either's Left failure/Right success convention. Thanks guys!

Pascal Voitot Dev

unread,
Feb 13, 2013, 2:52:54 AM2/13/13
to Drew Kutcharian, scala-user@googlegroups.com User
it depends on your error type... I tend to think we shouldn't forget the meaning of the word "exception" sometimes (even if some people also call it "goto" :) )

Alois Cochard

unread,
Feb 13, 2013, 6:20:54 AM2/13/13
to scala...@googlegroups.com
IMHO, it's better to return a Validation[Throwable, Option[User]]

I have custom Try which return a Validation, and I pimped scala.util.Exception.Catcher to have a 'toValidation' function.

Cheers

Josh Suereth

unread,
Feb 13, 2013, 7:53:58 AM2/13/13
to Alois Cochard, scala-user

I actually go this route, but with a custom error type:

final case class ONOES(msg: String, err: Option[Throwable])

You can usually make a good string representing what failed, but you don't always have an error.

Then, you need something like Try, but that let's you pick a good error message, like:

Validating("Could not load data") {
  ...
}

Combined with the ability to run "sanity checks" on data and aggregate errors, you can get a better user experience out of your error reporting.

Alois Cochard

unread,
Feb 13, 2013, 8:57:05 AM2/13/13
to scala...@googlegroups.com, Alois Cochard
Interesting!

Personally I like to create a small ADT for my errors, and then I 'Try { ... }.fail.map { case ... }' and depending of the throwable I choose the error I want, and then get rid of the throwable entirely.

Josh Suereth

unread,
Feb 13, 2013, 9:01:55 AM2/13/13
to Alois Cochard, scala-user

Most likely i could get rid of the throwable entirely, but my workflow is a bit more odd.   I like to be lazy with when I deal with errors, and try to keep my logic as close together as possible.  At least, that's my whole goal with having "convenient" higher-order methods rather than using try-catch directly....

Rex Kerr

unread,
Feb 13, 2013, 11:29:55 AM2/13/13
to Alois Cochard, scala...@googlegroups.com
It's convenient to have a hierarchy of types given that wrapping and unwrapping them gets awkward after a while.  Personally, I use, in order of complexity of what can be wrapped,
  Option
  Try
  Either
  May
  Tri
where the last two are equivalent to Option[Either[A,B]] and Try[Either[A,B]] (with special support for a None-like state, so perhaps actually Try[Option[Either[A,B]]]).  Of course you can just build up the pieces by yourself, but Tri encapsulates my error-handling workflow better than anything else I've come up with.  (Tri because of three possible states, which I amuse myself by calling Good, Bad, and Ugly--the last of which holds an exception.)

Anyway, I think the real point is "understand your error-handling needs and adopt a structure that satisfies them", which may include Try or Either or Option or all of the above.  Try's secret weapon is manipulation of a returned value in a bulletproof way; Option's advantage is its simplicity; Either's is its flexibility.  (May merges simplicity for simple cases with flexibility when you need an alternate type, and Tri attempts to merge all three, though I couldn't honestly call it "simple" any more.)

To a considerable extent, what you use is a matter of style, not a matter of what's "better".

  --Rex

Alois Cochard

unread,
Feb 14, 2013, 5:22:04 AM2/14/13
to scala...@googlegroups.com, Alois Cochard


On Wednesday, 13 February 2013 16:29:55 UTC, Rex Kerr wrote:
It's convenient to have a hierarchy of types given that wrapping and unwrapping them gets awkward after a while.  Personally, I use, in order of complexity of what can be wrapped,
  Option
  Try
  Either
  May
  Tri
where the last two are equivalent to Option[Either[A,B]] and Try[Either[A,B]] (with special support for a None-like state, so perhaps actually Try[Option[Either[A,B]]]).  Of course you can just build up the pieces by yourself, but Tri encapsulates my error-handling workflow better than anything else I've come up with.  (Tri because of three possible states, which I amuse myself by calling Good, Bad, and Ugly--the last of which holds an exception.)

Anyway, I think the real point is "understand your error-handling needs and adopt a structure that satisfies them", which may include Try or Either or Option or all of the above.  Try's secret weapon is manipulation of a returned value in a bulletproof way; Option's advantage is its simplicity; Either's is its flexibility.  (May merges simplicity for simple cases with flexibility when you need an alternate type, and Tri attempts to merge all three, though I couldn't honestly call it "simple" any more.)

To a considerable extent, what you use is a matter of style, not a matter of what's "better".

By better I meant Either VS Validation, the fact that Right mean Success is *just' convention, I think it's better to have a type which make that explicit, that's the a good reason for me to use Validation vs Either... and then comes  the great composable aspect of Validation, with map/flatMap/sequence/...

For the rest it's definitely a matter of style.
Reply all
Reply to author
Forward
0 new messages