Location of `Try`

66 views
Skip to first unread message

Heather Miller

unread,
May 15, 2012, 1:30:28 AM5/15/12
to scala-i...@googlegroups.com
Hi all, 

We introduced `Try` a while back along with SIP-14 (Futures). `Try` is analogous to `Either` with the exception that it's success-biased. That is, Either is symmetric, it has two type parameters that are wrapped (symmetrically) in either `Left` or `Right`. In general, by convention, `Either` can be used to represent a "successful" or a "failed" result, by representing some generic type in its right projection, and a subtype of Throwable in its left projection. However, this is by convention only, one can of course swap these projections (whether accidentally or purposefully) or one can represent two successful values in each projection if they so desire.

`Try`, on the other hand, is parameterized only on one type, with this success/failure use case in mind. That is, the successful case is wrapped in `Success` (parameterized on T) while the failed case is a `Throwable` wrapped in `Failure`.

`Try` comes from Twitter, who use it frequently in their codebase (see twitter/util on github), and who have found that it results in more readable and less error-prone code for this success/failure use case of `Either`.

Back then, we tentatively decided that it would go in package scala.util. 

However, this is a bit awkward because, as an analogue to `Either` (which lives in package scala and needs no import) `Try` lives in scala.util and requires the following import: 

import scala.util.{Try, Success, Failure}

So- the question is, are people happy with it this way? There was all kinds of talk-- eventually moving `Either` to the same package/sub-package as `Try`, for example. 

Cheers,
Heather

-- 
Heather Miller
Doctoral Assistant
EPFL, IC, LAMP

Roland Kuhn

unread,
May 15, 2012, 3:31:52 AM5/15/12
to scala-i...@googlegroups.com
Hi Heather,

given the somewhat heated discussion about biasing Either on scala-debate, and the good arguments put forth against maintaining two versions of Either, this seems a bit … strange. So, is it official that this construct will be in? I’m just asking because I just read these emails back-to-back and felt a large disconnect ;-)

Regards,

Roland

Roland Kuhn
Typesafe – The software stack for applications that scale.
twitter: @rolandkuhn


Heather Miller

unread,
May 15, 2012, 3:35:53 AM5/15/12
to scala-i...@googlegroups.com
Yes. It's official.

-- 
Heather Miller
Doctoral Assistant
EPFL, IC, LAMP

Heather Miller

unread,
May 15, 2012, 3:37:37 AM5/15/12
to scala-i...@googlegroups.com
Accidentally sent too early-- yes, it's official, according to previous informal discussions in LAMP.

-- 
Heather Miller
Doctoral Assistant
EPFL, IC, LAMP

√iktor Ҡlang

unread,
May 15, 2012, 4:55:55 AM5/15/12
to scala-i...@googlegroups.com
I am officially against its inclusion though.

Cheers,
--
Viktor Klang

Akka Tech Lead
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

Heiko Seeberger

unread,
May 15, 2012, 5:06:21 AM5/15/12
to scala-i...@googlegroups.com
Why not simply right bias Either?

Heiko

Roland Kuhn

unread,
May 15, 2012, 5:14:05 AM5/15/12
to scala-i...@googlegroups.com
Adding map/flatMap/filter with right-bias would get us the best of both worlds. If we want to be fancy we can include something like the following:

object Try {
def apply[T](body: => T): Either[Throwable, T] = try Right(body) catch { case NonFatal(ex) => Left(ex) }
}

this would be an easy way to enter it.

for {
v <- Try { computeValue }
if isOkay(v)
} yield transform(v)

Should this not be nice for everybody? No need to sacrifice the unbiased aspect for those who don’t want to use the newfangled stuff.

Regards,

Roland

Kevin Wright

unread,
May 15, 2012, 5:15:39 AM5/15/12
to scala-i...@googlegroups.com
I'm with √iktor and Heiko.

Right-bias Either.

Keep the explicit right-projection as well, for backward-compatibility.  Then either deprecate it, or (if demand for a symmetric union is high enough) migrate it to a trait so that it only needs to be mixed-in on demand.

--
Kevin Wright
mail: kevin....@scalatechnology.com
gtalk / msn : kev.lee...@gmail.com
vibe / skype: kev.lee.wright
steam: kev_lee_wright

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra

Stefan Zeiger

unread,
May 15, 2012, 5:17:16 AM5/15/12
to scala-i...@googlegroups.com
On 2012-05-15 11:14, Roland Kuhn wrote:
> Adding map/flatMap/filter with right-bias would get us the best of both worlds. If we want to be fancy we can include something like the following:
>
> object Try {
> def apply[T](body: => T): Either[Throwable, T] = try Right(body) catch { case NonFatal(ex) => Left(ex) }
> }

+1

Try[T] could just be Either[Throwable, T]. You may want a right-biased
Either with other kinds of errors than Throwable (e.g. accumulating
multiple errors in a Seq[Throwable]).

-sz

Jason Zaugg

unread,
May 15, 2012, 5:29:38 AM5/15/12
to scala-i...@googlegroups.com
The semantics are very different: The combinators in Try catch
exceptions, actively catering for non-total functions. [1]

Incidentally, the way it does this seems very dangerous: `catch e =>`
is usually not the right thing; it catches Error, ControlThrowable.

My vote would go to: keep Either and Try separate, and right-bias
Either. If it remains unbiased, it's not the end of the world, as we
can do so outside of the library without runtime penalty with and
inlined implicit class.

-jason


[1] https://github.com/scala/scala/blob/master/src/library/scala/util/Try.scala#L137

Roland Kuhn

unread,
May 15, 2012, 5:36:13 AM5/15/12
to scala-i...@googlegroups.com

May 15, 2012 kl. 11:29 skrev Jason Zaugg:

> On Tue, May 15, 2012 at 11:17 AM, Stefan Zeiger <sze...@novocode.com> wrote:
>> On 2012-05-15 11:14, Roland Kuhn wrote:
>>>
>>> Adding map/flatMap/filter with right-bias would get us the best of both
>>> worlds. If we want to be fancy we can include something like the following:
>>>
>>> object Try {
>>> def apply[T](body: => T): Either[Throwable, T] = try Right(body) catch
>>> { case NonFatal(ex) => Left(ex) }
>>> }
>>
>>
>> +1
>>
>> Try[T] could just be Either[Throwable, T]. You may want a right-biased
>> Either with other kinds of errors than Throwable (e.g. accumulating multiple
>> errors in a Seq[Throwable]).
>
> The semantics are very different: The combinators in Try catch
> exceptions, actively catering for non-total functions. [1]
>
Which brought me to the Try helper thingy above: just flatMap and return a Try { ... } to make this exception-wrapping explicit.

> Incidentally, the way it does this seems very dangerous: `catch e =>`
> is usually not the right thing; it catches Error, ControlThrowable.
>
Yeah, you’ll have noticed the NonFatal extractor above ;-) (has been in Akka for a while)

> My vote would go to: keep Either and Try separate, and right-bias
> Either. If it remains unbiased, it's not the end of the world, as we
> can do so outside of the library without runtime penalty with and
> inlined implicit class.
>
very true.

Regards,

Heiko Seeberger

unread,
May 15, 2012, 5:37:23 AM5/15/12
to scala-i...@googlegroups.com
On May 15, 2012, at 11:29 AM, Jason Zaugg wrote:

> Incidentally, the way it does this seems very dangerous: `catch e =>`
> is usually not the right thing; it catches Error, ControlThrowable.

Good catch. If Try is going to stay, shouldn't all occurrences of Throwable be replaced with Exception?

Heiko

Heather Miller

unread,
May 15, 2012, 5:39:16 AM5/15/12
to scala-i...@googlegroups.com
On Tuesday, May 15, 2012 at 11:29 AM, Jason Zaugg wrote:
On Tue, May 15, 2012 at 11:17 AM, Stefan Zeiger <sze...@novocode.com> wrote:
On 2012-05-15 11:14, Roland Kuhn wrote:

Adding map/flatMap/filter with right-bias would get us the best of both
worlds. If we want to be fancy we can include something like the following:

object Try {
  def apply[T](body: =>  T): Either[Throwable, T] = try Right(body) catch
{ case NonFatal(ex) =>  Left(ex) }
}


+1

Try[T] could just be Either[Throwable, T]. You may want a right-biased
Either with other kinds of errors than Throwable (e.g. accumulating multiple
errors in a Seq[Throwable]).

The semantics are very different: The combinators in Try catch
exceptions, actively catering for non-total functions. [1]
Yep, correct. 

Incidentally, the way it does this seems very dangerous: `catch e =>`
is usually not the right thing; it catches Error, ControlThrowable.
Good catch. This could also be improved by using the shiny, new NonFatal there:
(contributed by Viktor)

Mirco Dotta

unread,
May 15, 2012, 5:53:01 AM5/15/12
to scala-i...@googlegroups.com
As a side (but still related) question, is there any plan to clean up util.control.Exception


-- Mirco

√iktor Ҡlang

unread,
May 15, 2012, 6:07:22 AM5/15/12
to scala-i...@googlegroups.com
On Tue, May 15, 2012 at 11:14 AM, Roland Kuhn <goo...@rkuhn.info> wrote:
Adding map/flatMap/filter with right-bias would get us the best of both worlds. If we want to be fancy we can include something like the following:

object Try {
 def apply[T](body: => T): Either[Throwable, T] = try Right(body) catch { case NonFatal(ex) => Left(ex) }
}

this would be an easy way to enter it.

for {
 v <- Try { computeValue }
 if isOkay(v)
} yield transform(v)

Should this not be nice for everybody? No need to sacrifice the unbiased aspect for those who don’t want to use the newfangled stuff.

Amen
 

Regards,

Roland


May 15, 2012 kl. 11:06  skrev Heiko Seeberger:

> Why not simply right bias Either?
>
> Heiko
>
> On May 15, 2012, at 7:30 AM, Heather Miller wrote:
>
>> Hi all,
>>
>> We introduced `Try` a while back along with SIP-14 (Futures). `Try` is analogous to `Either` with the exception that it's success-biased. That is, Either is symmetric, it has two type parameters that are wrapped (symmetrically) in either `Left` or `Right`. In general, by convention, `Either` can be used to represent a "successful" or a "failed" result, by representing some generic type in its right projection, and a subtype of Throwable in its left projection. However, this is by convention only, one can of course swap these projections (whether accidentally or purposefully) or one can represent two successful values in each projection if they so desire.
>>
>> `Try`, on the other hand, is parameterized only on one type, with this success/failure use case in mind. That is, the successful case is wrapped in `Success` (parameterized on T) while the failed case is a `Throwable` wrapped in `Failure`.
>>
>> `Try` comes from Twitter, who use it frequently in their codebase (see twitter/util on github), and who have found that it results in more readable and less error-prone code for this success/failure use case of `Either`.
>>
>> Back then, we tentatively decided that it would go in package scala.util.
>>
>> However, this is a bit awkward because, as an analogue to `Either` (which lives in package scala and needs no import) `Try` lives in scala.util and requires the following import:
>>
>> import scala.util.{Try, Success, Failure}
>>
>> So- the question is, are people happy with it this way? There was all kinds of talk-- eventually moving `Either` to the same package/sub-package as `Try`, for example.
>>
>> Cheers,
>> Heather
>>
>> --
>> Heather Miller
>> Doctoral Assistant
>> EPFL, IC, LAMP
>> http://people.epfl.ch/heather.miller
>>
>

Roland Kuhn
Typesafe – The software stack for applications that scale.
twitter: @rolandkuhn





--
Viktor Klang

Akka Tech Lead
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

Francois

unread,
May 15, 2012, 7:23:12 AM5/15/12
to scala-i...@googlegroups.com, Roland Kuhn
On 15/05/2012 09:31, Roland Kuhn wrote:
> Hi Heather,
>
> given the somewhat heated discussion about biasing Either on
> scala-debate, and the good arguments put forth against maintaining two
> versions of Either, this seems a bit … strange. So, is it official
> that this construct will be in? I’m just asking because I just read
> these emails back-to-back and felt a large disconnect ;-)
>

I, to, read the two threads one after the other, and felt like you.

--
Francois ARMAND
http://fanf42.blogspot.com
http://www.normation.com

Jonas Bonér

unread,
May 15, 2012, 7:40:42 AM5/15/12
to scala-i...@googlegroups.com
On Tue, May 15, 2012 at 11:15 AM, Kevin Wright <kev.lee...@gmail.com> wrote:
I'm with √iktor and Heiko.

Right-bias Either.

+1 - better to fix problems rather than adding a level of indirection to work around it



--
Jonas Bonér
CTO

Typesafe - The software stack for applications that scale
Phone: +46 733 777 123
Twitter: @jboner

Heather Miller

unread,
May 15, 2012, 7:59:56 AM5/15/12
to scala-i...@googlegroups.com
Moved this to scala-debate, probably best to redirect there.

Thanks,
Heather

-- 
Heather Miller
Doctoral Assistant
EPFL, IC, LAMP

Reply all
Reply to author
Forward
0 new messages