Naming in Futures - SIP-14, Futures, Try, Either and Option

514 views
Skip to first unread message

Reuben Doetsch

unread,
Nov 8, 2012, 8:32:38 PM11/8/12
to scala...@googlegroups.com, nat...@technically.us
Hey Everyone,

I am working on a 2.10 integration branch for the new version of async dispatch (Can't get enough of 2.10 -- it's that good)


Dispatch used it's own Future implementation because it was created before the SIP was live.

I wanted to standardize the implements and use scala.concurrent.Future for 2.10 and a provided implementation for versions lower than 2.10.

So far so good, as I have ported all the code scala.concurrent.Future but there is one breaking change where Nathan or I (creator of Dispatch) does not want to break existing code.  Dispatch contains an "either" method which transforms the Future[A] to a Future[Either[_,A]] which is used heavily in the library. scala.concurrent.Future also contains an either method.

I do not want to break compatibility for a large library and I think that the naming of the either method in Future is strange. The method is not very descriptive and there already exists a Either class in the standard library which now could easily be wrongly associated with having something to do with the either method. I don't care if the method from Future to either exists or not (since I am adding a Future pimp where I can add this), but I do care about the method named either.

Are people very strongly in favor of the name either for the method which choose the first completed future. Wouldn't this more aptly be named, "firstCompleted", "firstComplete", or "getFirstCompleted" or something which describes what it is doing?

Thanks,
Reuben

Heather Miller

unread,
Nov 9, 2012, 3:17:14 AM11/9/12
to scala...@googlegroups.com, nat...@technically.us
I think that the reasoning was to differentiate `either` from `firstCompletedOf` (on the Future companion object) which returns the first completed future of a TraversableOnce[Future[T]], i.e. to differentiate between the case of exactly two futures and a collection of an arbitrary number of futures.

While your proposition, i.e. renaming `either` to `firstCompleted` or `firstCompletedOf` or similar is one we'd normally be open to (it's a change I doubt many would have strong feelings against), the trouble is that we've already cut the second RC of 2.10.0, which could very well be 2.10.0-FINAL. I'm afraid it might be too late to rename new methods. Given that, we'd have to go through a deprecation cycle upon the next major release before we could remove it.

Cheers,
Heather

-- 
Heather Miller
Doctoral Assistant
EPFL, IC, LAMP

Heather Miller

unread,
Nov 9, 2012, 3:19:18 AM11/9/12
to scala...@googlegroups.com, nat...@technically.us
To add a bit of context, I think that the only reason that `either` was ultimately chosen is because it implies that there are only two possibilities-- either A or B. Whereas something else, like firstCompleted intuitively makes no guarantees on the number of futures that we might start with.

Cheers,
Heather

-- 
Heather Miller
Doctoral Assistant
EPFL, IC, LAMP



nicola...@gmail.com

unread,
Nov 9, 2012, 5:06:32 AM11/9/12
to scala...@googlegroups.com, nat...@technically.us
I think either is a nicer name for choosing either of two futures than to map Right on a future.

--
Sent from an IBM Model M, 15 August 1989.

√iktor Ҡlang

unread,
Nov 9, 2012, 5:52:23 AM11/9/12
to <scala-sips@googlegroups.com>, Nathan Hamblen
This is the sort of discussion that would have been quite much nicer to have 6 months ago.
(and also why it is important to get involved in SIPs if one has a stake in it)

Cheers,


On Fri, Nov 9, 2012 at 2:32 AM, Reuben Doetsch <hja...@gmail.com> wrote:



--
Viktor Klang

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

Twitter: @viktorklang

martin odersky

unread,
Nov 9, 2012, 6:02:32 AM11/9/12
to scala...@googlegroups.com
On Fri, Nov 9, 2012 at 11:52 AM, √iktor Ҡlang <viktor...@gmail.com> wrote:
This is the sort of discussion that would have been quite much nicer to have 6 months ago.
(and also why it is important to get involved in SIPs if one has a stake in it)

Yes I agree. In the future, please get involved in SIPs! That's what they are for.

 - Martin

 



--
Martin Odersky
Prof., EPFL and Chairman, Typesafe
PSED, 1015 Lausanne, Switzerland
Tel. EPFL: +41 21 693 6863
Tel. Typesafe: +41 21 691 4967

Daniel Sobral

unread,
Nov 9, 2012, 7:35:05 AM11/9/12
to scala...@googlegroups.com, Nathan Hamblen
I'd like to point out that I did raise this issue here in this list, though I never mentioned the method either explicitly (which I now regret).

However, if you followed up on my request for a method that converts a Future[T] into a Future[Either[Exception, T]], I'm pretty sure either's name would have come up.
--
Daniel C. Sobral

I travel to the future all the time.

√iktor Ҡlang

unread,
Nov 9, 2012, 7:41:47 AM11/9/12
to <scala-sips@googlegroups.com>, Nathan Hamblen
What happens if the Future[Either[Exception, T]] is failed?

Chris Marshall

unread,
Nov 9, 2012, 7:41:54 AM11/9/12
to scala...@googlegroups.com
I think it is fair to say that general experience is that people only actually get involved after the API is roughly worked out and it doesn't quite look like they expected. It might be a better idea to work this observation into the SIP workflow - I know it must be extremely frustrating for the people behind the SIP.

How would it be worked into the SIP workflow? By having less up-front discussion and rushing headlong into an (intentionally poor) implementation which is presented as a fait accompli to the community at large, who then go ballistic and offer vocal feedback. I understand this approach is being trialed by the JDK8 lambda guys.

Chris

√iktor Ҡlang

unread,
Nov 9, 2012, 7:51:19 AM11/9/12
to <scala-sips@googlegroups.com>
There's no solution to this problem, there will always be people who migrate years after something is released and start commenting about perceived deficiencies.
(I for one wouldn't want to be on Lambda – 90% of the feedback is just not constructive.)

However, I think people generally need to engage more in the things which they have a stake in, or just delegate to others and forfeit their right to whine – which is why I spent a lot of my spare time (which there is very little of) to be involved in SIP-14 – to be a part of the solution and not the problem.

Cheers,

Daniel Sobral

unread,
Nov 9, 2012, 7:59:50 AM11/9/12
to scala...@googlegroups.com
On Fri, Nov 9, 2012 at 10:41 AM, Chris Marshall <oxbow...@gmail.com> wrote:
I think it is fair to say that general experience is that people only actually get involved after the API is roughly worked out and it doesn't quite look like they expected. It might be a better idea to work this observation into the SIP workflow - I know it must be extremely frustrating for the people behind the SIP.

How would it be worked into the SIP workflow? By having less up-front discussion and rushing headlong into an (intentionally poor) implementation which is presented as a fait accompli to the community at large, who then go ballistic and offer vocal feedback. I understand this approach is being trialed by the JDK8 lambda guys.

I'm not sure if that's humor or not, nor do I deny the essential truth of it, but lol!
 

Chris


On Fri, Nov 9, 2012 at 10:52 AM, √iktor Ҡlang <viktor...@gmail.com> wrote:
This is the sort of discussion that would have been quite much nicer to have 6 months ago.
(and also why it is important to get involved in SIPs if one has a stake in it)

Cheers,

Daniel Sobral

unread,
Nov 9, 2012, 8:01:13 AM11/9/12
to scala...@googlegroups.com, Nathan Hamblen
On Fri, Nov 9, 2012 at 10:41 AM, √iktor Ҡlang <viktor...@gmail.com> wrote:
What happens if the Future[Either[Exception, T]] is failed?

What do you mean by "is failed"?

√iktor Ҡlang

unread,
Nov 9, 2012, 8:04:04 AM11/9/12
to <scala-sips@googlegroups.com>, Nathan Hamblen
contains a Failure instead of a Success

Ismael Juma

unread,
Nov 9, 2012, 8:07:42 AM11/9/12
to scala...@googlegroups.com
On Fri, Nov 9, 2012 at 12:51 PM, √iktor Ҡlang <viktor...@gmail.com> wrote:
However, I think people generally need to engage more in the things which they have a stake in, or just delegate to others and forfeit their right to whine – which is why I spent a lot of my spare time (which there is very little of) to be involved in SIP-14 – to be a part of the solution and not the problem.

I agree that people should get involved as early as they can. They should not forfeit the right to provide feedback late in the process though. As long as they understand that it may be harder and take more time for actions to be taken based on the feedback. After all, software is constantly improving and part of the reason is that feedback happens continuously.

Best,
Ismael

Daniel Sobral

unread,
Nov 9, 2012, 8:09:38 AM11/9/12
to scala...@googlegroups.com, Nathan Hamblen
On Fri, Nov 9, 2012 at 11:04 AM, √iktor Ҡlang <viktor...@gmail.com> wrote:
contains a Failure instead of a Success

It becomes a Success(Left(ex)). The point of toEither (Dispatch's Promise.either) is pretty much making sure methods called on it will work as if it was a success. For example, map and flatMap should receive and act on the Either, be it a Left or a Right.

Reuben Doetsch

unread,
Nov 9, 2012, 8:10:21 AM11/9/12
to scala...@googlegroups.com
Thanks everyone for the reply,

@Heather - I understand why the general idea behind why it was named, but just had an issue with the name "either" (for the reasons listed). Obviously many of them are selfish in that I want to be able to migrate and create a easy migration from dispatch_2.9.2 to dispatch_2.10.0. Even without my selfish interest, either seems like a strange name ( https://twitter.com/n8han/status/265902526036066305 -- please don't crucify for me using Twitter for proof of anything).

@oxbows - I don't think anything can be done to the SIP workflow other than what Viktor said, which is to be more involved. 

@martin, @viktor - I wish I had been more involved in the process ( I am relatively new to Scala ), but I think Nathan was involved early on and added SIP methods to the Future, but either was added after this effort had been done. The SIP changed a lot and I think Nathan only looked at it at a few snapshots in time. I wanted to bring this up before 2.10.0-FINAL came out, but didn't realize that everyone is thinking only two RC's. 

I am assuming by all the messages that there is no way to start a conversation about changing the name right now and for dispatch I should start migrating code to use a new name. If it helps, I will volunteer my time to change documentation, code, or whatever related to the name.

Thanks again,

Reuben

Aleksandar Prokopec

unread,
Nov 9, 2012, 8:11:30 AM11/9/12
to scala...@googlegroups.com, Daniel Sobral, Nathan Hamblen

On 11/9/12 2:01 PM, Daniel Sobral wrote:
On Fri, Nov 9, 2012 at 10:41 AM, √iktor Ҡlang <viktor...@gmail.com> wrote:
What happens if the Future[Either[Exception, T]] is failed?

What do you mean by "is failed"?
 


I think he means that you do:

f.either.map(x => (throw Exception): Either[Exception, T])

which would give you back a Future[Either[Exception, T]], but the future itself would be failed, whereas a user might expect the future to contain a Left(Exception) instead.

Cheers,
Alex

√iktor Ҡlang

unread,
Nov 9, 2012, 8:12:29 AM11/9/12
to <scala-sips@googlegroups.com>, Nathan Hamblen
But that is my point, there is no way to enforce that at a type level.

def bippy(f: Future[Either[Exception, T]]) = …

bippy(Future.failed(new OhnoesException))

√iktor Ҡlang

unread,
Nov 9, 2012, 8:19:40 AM11/9/12
to <scala-sips@googlegroups.com>
On Fri, Nov 9, 2012 at 2:10 PM, Reuben Doetsch <hja...@gmail.com> wrote:
Thanks everyone for the reply,

@Heather - I understand why the general idea behind why it was named, but just had an issue with the name "either" (for the reasons listed). Obviously many of them are selfish in that I want to be able to migrate and create a easy migration from dispatch_2.9.2 to dispatch_2.10.0. Even without my selfish interest, either seems like a strange name ( https://twitter.com/n8han/status/265902526036066305 -- please don't crucify for me using Twitter for proof of anything).

We were discussing quite a few names: "or", "race" ("or" was problematic because people assumed it to take the first successful value) ("race" is a problematic name)
 

@oxbows - I don't think anything can be done to the SIP workflow other than what Viktor said, which is to be more involved. 

@martin, @viktor - I wish I had been more involved in the process ( I am relatively new to Scala ), but I think Nathan was involved early on and added SIP methods to the Future, but either was added after this effort had been done. The SIP changed a lot and I think Nathan only looked at it at a few snapshots in time. I wanted to bring this up before 2.10.0-FINAL came out, but didn't realize that everyone is thinking only two RC's. 

Things like these need to be raised pre-RC (there might only be one) – but I definitely want them to be raised, so please get involved sooner :-)
 

I am assuming by all the messages that there is no way to start a conversation about changing the name right now and for dispatch I should start migrating code to use a new name. If it helps, I will volunteer my time to change documentation, code, or whatever related to the name.

val firstOf = future2 <insert suggested name here> future2

val firstOf = future firstCompletedOf future2 //Clashes with Future.firstCompletedOf and is also quite unpleasant visually

val firstOf = future race future2

val firstOf = future || future2 // doesn't have the right semantics, people expect short-circuit

Perhaps the right solution is to remove the method?


Cheers,

Daniel Sobral

unread,
Nov 9, 2012, 8:29:09 AM11/9/12
to scala...@googlegroups.com, Nathan Hamblen
On Fri, Nov 9, 2012 at 11:12 AM, √iktor Ҡlang <viktor...@gmail.com> wrote:
But that is my point, there is no way to enforce that at a type level.

def bippy(f: Future[Either[Exception, T]]) = …

bippy(Future.failed(new OhnoesException))

I'm sorry but that's completely outside scope.

See, it is my intention as *the caller* to ensure that the *receiver* will get a future where any present failure becomes a success of a left.

It's not about what I'm receiving, but about what I'm sending.

reuben doetsch

unread,
Nov 9, 2012, 8:29:41 AM11/9/12
to scala...@googlegroups.com
Thanks Viktor,

How about

val firstOf = future firstCompleted future2

since adding the "firstCompletedOf" implies there are multiple objects on the right side (by using the word of)

or 

val firstOf = future getOrFirst future2


Reuben 
--
Thanks,

Reuben Doetsch
CTO & CoFounder Sportaneous.com


Daniel Sobral

unread,
Nov 9, 2012, 8:33:04 AM11/9/12
to scala...@googlegroups.com, Nathan Hamblen
On Fri, Nov 9, 2012 at 11:29 AM, Daniel Sobral <dcso...@gmail.com> wrote:

On Fri, Nov 9, 2012 at 11:12 AM, √iktor Ҡlang <viktor...@gmail.com> wrote:
But that is my point, there is no way to enforce that at a type level.

def bippy(f: Future[Either[Exception, T]]) = …

bippy(Future.failed(new OhnoesException))

I'm sorry but that's completely outside scope.

See, it is my intention as *the caller* to ensure that the *receiver* will get a future where any present failure becomes a success of a left.

It's not about what I'm receiving, but about what I'm sending.

I thought of another point here. If I were "bippy" and wanted to ensure I would not get a failure, I'd get a normal feature, and then, myself, call either-or-whatever on it.

Chris Marshall

unread,
Nov 9, 2012, 8:35:07 AM11/9/12
to scala...@googlegroups.com
I am always about the lols

√iktor Ҡlang

unread,
Nov 9, 2012, 8:35:43 AM11/9/12
to <scala-sips@googlegroups.com>, Nathan Hamblen
I'd suggest using the "transform" method instead of involving Either.

√iktor Ҡlang

unread,
Nov 9, 2012, 8:36:31 AM11/9/12
to <scala-sips@googlegroups.com>, Nathan Hamblen
Exactly, so there is not much need for the Either-thingy. Also, "transform" is a very nice method.

Philipp Haller

unread,
Nov 9, 2012, 8:42:38 AM11/9/12
to scala...@googlegroups.com
On Nov 9, 2012, at 2:19 PM, √iktor Ҡlang wrote:
I am assuming by all the messages that there is no way to start a conversation about changing the name right now and for dispatch I should start migrating code to use a new name. If it helps, I will volunteer my time to change documentation, code, or whatever related to the name.

val firstOf = future2 <insert suggested name here> future2

val firstOf = future firstCompletedOf future2 //Clashes with Future.firstCompletedOf and is also quite unpleasant visually

val firstOf = future race future2

val firstOf = future || future2 // doesn't have the right semantics, people expect short-circuit

Perhaps the right solution is to remove the method?

I think that removing the method could be a workable solution. After all, it's got a very simple implementation in terms of Promise and tryComplete.

Cheers,
Philipp

Philipp Haller

unread,
Nov 9, 2012, 8:44:41 AM11/9/12
to scala...@googlegroups.com
On Nov 9, 2012, at 2:42 PM, Philipp Haller wrote:


On Nov 9, 2012, at 2:19 PM, √iktor Ҡlang wrote:
I am assuming by all the messages that there is no way to start a conversation about changing the name right now and for dispatch I should start migrating code to use a new name. If it helps, I will volunteer my time to change documentation, code, or whatever related to the name.

val firstOf = future2 <insert suggested name here> future2

val firstOf = future firstCompletedOf future2 //Clashes with Future.firstCompletedOf and is also quite unpleasant visually

val firstOf = future race future2

val firstOf = future || future2 // doesn't have the right semantics, people expect short-circuit

Perhaps the right solution is to remove the method?

I think that removing the method could be a workable solution. After all, it's got a very simple implementation in terms of Promise and tryComplete.

As an end result I mean.
How to go about deprecation etc. is a separate issue.

Aleksandar Prokopec

unread,
Nov 9, 2012, 8:46:16 AM11/9/12
to scala...@googlegroups.com, Philipp Haller
On 11/9/12 2:42 PM, Philipp Haller wrote:

On Nov 9, 2012, at 2:19 PM, √iktor Ҡlang wrote:
I am assuming by all the messages that there is no way to start a conversation about changing the name right now and for dispatch I should start migrating code to use a new name. If it helps, I will volunteer my time to change documentation, code, or whatever related to the name.

val firstOf = future2 <insert suggested name here> future2

val firstOf = future firstCompletedOf future2 //Clashes with Future.firstCompletedOf and is also quite unpleasant visually

val firstOf = future race future2

val firstOf = future || future2 // doesn't have the right semantics, people expect short-circuit

Perhaps the right solution is to remove the method?

I think that removing the method could be a workable solution. After all, it's got a very simple implementation in terms of Promise and tryComplete.

Cheers,
Philipp

I agree with this - seems like the safest course of action. It can always be added back with a different name in a later release if necessary.

Cheers,
Alex

√iktor Ҡlang

unread,
Nov 9, 2012, 8:47:06 AM11/9/12
to <scala-sips@googlegroups.com>, Philipp Haller
I also agree with this.
But that means we need to cut an RC3.

Philipp Haller

unread,
Nov 9, 2012, 8:48:44 AM11/9/12
to Aleksandar Prokopec, scala...@googlegroups.com
And that addition could come in a follow-up SIP, such as SIP-14b. People would then hopefully get involved earlier with SIP-14b.

Philipp

Daniel Sobral

unread,
Nov 9, 2012, 8:59:13 AM11/9/12
to scala...@googlegroups.com, Nathan Hamblen
Transform can't be used to feed a pattern match, and it's excessively verbose when I just want an Either. Hey, Either has precedence: it was here first. Be nice to it.

Rex Kerr

unread,
Nov 9, 2012, 10:00:19 AM11/9/12
to scala...@googlegroups.com
On Fri, Nov 9, 2012 at 8:19 AM, √iktor Ҡlang <viktor...@gmail.com> wrote:

val firstOf = future || future2 // doesn't have the right semantics, people expect short-circuit

val firstOf = future | future2  // People don't expect short-circuit!

  --Rex

P.S. I prefer not using "either" to mean "or".  For example: we could rename this method either remove it entirely.  Huh?!

Reuben Doetsch

unread,
Nov 10, 2012, 10:57:27 AM11/10/12
to scala...@googlegroups.com
@Viktor + @Martin - What is the best course of action?

√iktor Ҡlang

unread,
Nov 10, 2012, 11:31:52 AM11/10/12
to <scala-sips@googlegroups.com>
Reuben: To achieve what end?

reuben doetsch

unread,
Nov 10, 2012, 11:54:09 AM11/10/12
to scala...@googlegroups.com
Based on this thread it seems like many people are in favor of either (pun not intended) a change of name or a deprecation. I know personally I am and it would be great for backwards compatibility with dispatch.

I would love to see if it possible to either get a SIP-14B rolling, or change the name or deprecate?

I know it might be too late for 2.10, but if something could happen before 2.10.0-FINAL it would be great. Again I free all day and tomorrow to do any necessary work if people agree on it.

If we the change won't happen, I also would love to know so I can figure out a backwards solution to write and release dispatch for 2.10.

Thanks for taking my concern,

Reuben

Daniel Sobral

unread,
Nov 10, 2012, 11:56:25 AM11/10/12
to scala...@googlegroups.com
Personally, I think the best course of action at this point is to keep the name "either", unless many more people complain about it once 2.10.0 is out.

√iktor Ҡlang

unread,
Nov 10, 2012, 12:02:54 PM11/10/12
to <scala-sips@googlegroups.com>
The only option I see is to remove it completely in the next Scala 2.10 RC (if there is another one).

As for having a method that lifts a Future[T] to Future[Either[Throwable, T]] I think I've already been clear on the fallacy of such a method.

Cheers,

Ismael Juma

unread,
Nov 10, 2012, 12:05:42 PM11/10/12
to scala...@googlegroups.com
On Sat, Nov 10, 2012 at 5:02 PM, √iktor Ҡlang <viktor...@gmail.com> wrote:
The only option I see is to remove it completely in the next Scala 2.10 RC (if there is another one).

It looks like RC3 may be needed after all:


Ismael

Rex Kerr

unread,
Nov 10, 2012, 12:42:35 PM11/10/12
to scala...@googlegroups.com
The more I think about it, the less I like the name either.  It implies that it might have something to do with success or failure, which it doesn't, just order of completion.

So I would suggest one of
  (a) Rename either | and zip &
  (b) Remove either, and have its code as an example in the docs
  (c) Rename either to fastest or soonest or somesuch
but not leaving it as is.

  --Rex

reuben doetsch

unread,
Nov 10, 2012, 12:59:05 PM11/10/12
to scala...@googlegroups.com
I'm +1 for b or c ( I think fastest is the best name proposed). I think | and & will confuse people, since people might assume they have something to do with the Boolean operation.

Rex Kerr

unread,
Nov 10, 2012, 1:11:32 PM11/10/12
to scala...@googlegroups.com
Well, I guess you're right, since zip is &, but fastest is not | in the normal sense (it's not the first that's true, it's the first whether true or false).
  --Rex

Daniel Sobral

unread,
Nov 10, 2012, 2:37:29 PM11/10/12
to scala...@googlegroups.com
On Sat, Nov 10, 2012 at 3:02 PM, √iktor Ҡlang <viktor...@gmail.com> wrote:
The only option I see is to remove it completely in the next Scala 2.10 RC (if there is another one).

As for having a method that lifts a Future[T] to Future[Either[Throwable, T]] I think I've already been clear on the fallacy of such a method.

Except for never having gone over my use cases and proposed alternatives, after having asked for my use cases.

I'm in complete disagreement with you in this matter. I don't think it's a fallacy, I think your argument against it was a fallacy, I think it's useful, and I haven't seen a single alternative proposed except re-implement that method through implicits or at every usage site.

Rex Kerr

unread,
Nov 10, 2012, 2:51:01 PM11/10/12
to scala...@googlegroups.com
Well, Viktor did point out a problem: the types don't tell you that Future will always succeed in that case, which is presumably the desired behavior.

However, I would just turn that back around and say: well, that's the fault of the library for not allowing the specification in types of a future that is "guaranteed" to succeed (because failures get packaged).  A runtime guarantee is better than nothing.

For example, maybe you want to Await something.  You could Try(Await(blah)), or you could Await something that will package any exceptions.  There are cases where the latter would be easier.

I am not convinced that Either should be used instead of Try.  (Try really should have a toEither method, or at least fold.  Transform is cool and all, but transform(x=>Try(Right(x)),t=>Try(Left(t))).flatten is such a mouthful.)

Anyway, most of these things could be added in 2.10.1; no rush for 2.10.0.  The `either` method is the only awkward part for now.

  --Rex

Daniel Sobral

unread,
Nov 10, 2012, 3:01:20 PM11/10/12
to scala...@googlegroups.com
On Sat, Nov 10, 2012 at 5:51 PM, Rex Kerr <ich...@gmail.com> wrote:
Well, Viktor did point out a problem: the types don't tell you that Future will always succeed in that case, which is presumably the desired behavior.

Err, no, that is not the desired behavior, as I latter explained. In fact, there's no need to do that, because whoever is calling Future can use onSuccess or transform.

The desire is to transform a possible failing Future into a non-failing Future at the Future generation site.
 

However, I would just turn that back around and say: well, that's the fault of the library for not allowing the specification in types of a future that is "guaranteed" to succeed (because failures get packaged).  A runtime guarantee is better than nothing.

For example, maybe you want to Await something.  You could Try(Await(blah)), or you could Await something that will package any exceptions.  There are cases where the latter would be easier.

I am not convinced that Either should be used instead of Try.  (Try really should have a toEither method, or at least fold.  Transform is cool and all, but transform(x=>Try(Right(x)),t=>Try(Left(t))).flatten is such a mouthful.)

Anyway, most of these things could be added in 2.10.1; no rush for 2.10.0.  The `either` method is the only awkward part for now.

+1 on not having to add anything right now.

I'm not as repelled by "either" as others, though it's an unfortunate name.

Rex Kerr

unread,
Nov 10, 2012, 3:07:08 PM11/10/12
to scala...@googlegroups.com

On Sat, Nov 10, 2012 at 3:01 PM, Daniel Sobral <dcso...@gmail.com> wrote:
On Sat, Nov 10, 2012 at 5:51 PM, Rex Kerr <ich...@gmail.com> wrote:
Well, Viktor did point out a problem: the types don't tell you that Future will always succeed in that case, which is presumably the desired behavior.

Err, no, that is not the desired behavior, as I latter explained. In fact, there's no need to do that, because whoever is calling Future can use onSuccess or transform.

The desire is to transform a possible failing Future into a non-failing Future at the Future generation site.
 

That's what I was trying to say.  But I was also trying to say: your types cannot tell you, even if you want them to, that you have generated a non-failing Future.  I thought that was Viktor's point; maybe I was mistaken.

  --Rex

Som Snytt

unread,
Nov 10, 2012, 5:28:13 PM11/10/12
to scala...@googlegroups.com
On Sat, Nov 10, 2012 at 9:42 AM, Rex Kerr <ich...@gmail.com> wrote:
The more I think about it, the less I like the name either.  It implies that it might have something to do with success or failure, which it doesn't, just order of completion.

So I would suggest one of
  (b) Remove either, and have its code as an example in the docs 

+1


 P.S. I prefer not using "either" to mean "or".  For example: we could rename this method either remove it entirely.  Huh?!

"either" means "and".  For example: "Me either."  As the kids say.

 

√iktor Ҡlang

unread,
Nov 10, 2012, 5:31:41 PM11/10/12
to scala...@googlegroups.com

That was exactly my point.

>
>   --Rex

Reuben Doetsch

unread,
Nov 10, 2012, 6:09:15 PM11/10/12
to scala...@googlegroups.com
There are two different discussions here -- For right now the battle of whether or not a toEither method is useful for Future is not settled.  

On the other hand, everyone seems to be in favor of either deprecating "either" or changing the name? 

If we are going to have a RC-3 for the breaking bug mentioned above, could we add deprecating either for right now as part of that? We can always add back in either when renamed later. Again sorry for being annoying about a resolution (I know there are a lot of stackholders involved), but to release a version of dispatch that works with scala Future's it would be helpful for a resolution (either in the affirmative or the negative).

Thanks

Reuben 

Derek Williams

unread,
Nov 10, 2012, 8:05:36 PM11/10/12
to scala...@googlegroups.com
I'm all for limiting the methods on Future as much as possible, and allowing others to use their own implicits to add additional methods, so my vote would be deprecating/removal.

And a little bit related, and not sure if it was mentioned at all, but Future's transform method isn't very useful in it's current form (it can't turn a Future into a Future[Either[Throwable, A]], for instance). It would be much more useful if it had a similar signature to Try's transform, and also be more consistent. Is the current inconsistency by design, or is there a mistake?
--
Derek Williams

√iktor Ҡlang

unread,
Nov 11, 2012, 6:55:55 AM11/11/12
to <scala-sips@googlegroups.com>
On Sun, Nov 11, 2012 at 2:05 AM, Derek Williams <de...@fyrie.net> wrote:
I'm all for limiting the methods on Future as much as possible, and allowing others to use their own implicits to add additional methods, so my vote would be deprecating/removal.

I don't see why it would need to be deprecated, it has technically never been officially released.
 

And a little bit related, and not sure if it was mentioned at all, but Future's transform method isn't very useful in it's current form (it can't turn a Future into a Future[Either[Throwable, A]], for instance).

Which I think I already proved to be impossible at the type level.
 
It would be much more useful if it had a similar signature to Try's transform, and also be more consistent. Is the current inconsistency by design, or is there a mistake?

you mean making it a flatMap2 instead of a map2?
 


On Sat, Nov 10, 2012 at 4:09 PM, Reuben Doetsch <hja...@gmail.com> wrote:
There are two different discussions here -- For right now the battle of whether or not a toEither method is useful for Future is not settled.  

On the other hand, everyone seems to be in favor of either deprecating "either" or changing the name? 

If we are going to have a RC-3 for the breaking bug mentioned above, could we add deprecating either for right now as part of that? We can always add back in either when renamed later. Again sorry for being annoying about a resolution (I know there are a lot of stackholders involved), but to release a version of dispatch that works with scala Future's it would be helpful for a resolution (either in the affirmative or the negative).

Thanks

Reuben 

On Saturday, November 10, 2012 5:31:43 PM UTC-5, Viktor Klang wrote:


On Nov 10, 2012 9:07 PM, "Rex Kerr" <ich...@gmail.com> wrote:
>
>
> On Sat, Nov 10, 2012 at 3:01 PM, Daniel Sobral <dcso...@gmail.com> wrote:


>>
>> On Sat, Nov 10, 2012 at 5:51 PM, Rex Kerr <ich...@gmail.com> wrote:
>>>
>>> Well, Viktor did point out a problem: the types don't tell you that Future will always succeed in that case, which is presumably the desired behavior.
>>
>>
>> Err, no, that is not the desired behavior, as I latter explained. In fact, there's no need to do that, because whoever is calling Future can use onSuccess or transform.
>>
>> The desire is to transform a possible failing Future into a non-failing Future at the Future generation site.
>>  
>
>
> That's what I was trying to say.  But I was also trying to say: your types cannot tell you, even if you want them to, that you have generated a non-failing Future.  I thought that was Viktor's point; maybe I was mistaken.

That was exactly my point.

>
>   --Rex




--
Derek Williams

Rex Kerr

unread,
Nov 11, 2012, 7:52:18 AM11/11/12
to scala...@googlegroups.com
On Sun, Nov 11, 2012 at 6:55 AM, √iktor Ҡlang <viktor...@gmail.com> wrote:

On Sun, Nov 11, 2012 at 2:05 AM, Derek Williams <de...@fyrie.net> wrote:

And a little bit related, and not sure if it was mentioned at all, but Future's transform method isn't very useful in it's current form (it can't turn a Future into a Future[Either[Throwable, A]], for instance).

Which I think I already proved to be impossible at the type level.

Only for a very strange definition of impossible:
  (a) It works perfectly at runtime but keeping the Future signature is not good enough, and
  (b) No alternative signature is provided, so you're out of luck!
 
  --Rex

P.S.  What is future.map(x => Right(x)).recover{ case t => Left(t) }, anyway?

√iktor Ҡlang

unread,
Nov 11, 2012, 9:32:32 AM11/11/12
to <scala-sips@googlegroups.com>
My point is:

if you are the consumer of an method that returns Future[Either[Throwable, T]], then you cannot _know_ that it won't ever be a failed Future, also, you now turn all Future error handling code that operates on Failure into a mess since you've subverted it into a Success.

if you are the receiver of a method parameter of a Future[Either[Throwable, T]] then you cannot _know_ that it won't ever be a failed Future, also, you now turn all Future error handling code that operates on Failure into a mess since you've subverted it into a Success.

A Future is already a logical Either[Throwable, T] since it wraps a Try.

Also, having a Future[Either[Throwable, T]] is a _solution_ not a _problem_/_usecase_ so we cannot even begin to offer counter-solutions.

So: 

1) Why would you need Future[Either[Throwable, T]]?
2) would it suffice with a mapAll and a flatMapAll that is of the shape Try[T] => U and Try[T] => Try[U]?

Cheers,

√iktor Ҡlang

unread,
Nov 11, 2012, 9:36:03 AM11/11/12
to <scala-sips@googlegroups.com>
As for a toEither method I'd suggest going with the same approach as the collection's "to" method.

√iktor Ҡlang

unread,
Nov 11, 2012, 9:36:46 AM11/11/12
to <scala-sips@googlegroups.com>
And as for the "either" method, I'm not against dropping it completely in RC3 if it is the consensus.

Rex Kerr

unread,
Nov 11, 2012, 1:04:07 PM11/11/12
to scala...@googlegroups.com
On Sun, Nov 11, 2012 at 9:32 AM, √iktor Ҡlang <viktor...@gmail.com> wrote:
My point is:

if you are the consumer of an method that returns Future[Either[Throwable, T]], then you cannot _know_ that it won't ever be a failed Future, also, you now turn all Future error handling code that operates on Failure into a mess since you've subverted it into a Success.

Well, sure.  But it's not really any different from--in fact it's better than--

  def p(xs: List[Int]) = xs.head > 0
  val xs = (1 :: someRandomList)
  if (p(xs)) ???

I don't know that I have a nonempty list, so it's a slightly dangerous thing to do.  Not completely bulletproof.  But with adequate comments it can be an okay solution in some circumstances.
 
A Future is already a logical Either[Throwable, T] since it wraps a Try.

Also, having a Future[Either[Throwable, T]] is a _solution_ not a _problem_/_usecase_ so we cannot even begin to offer counter-solutions.

Backwards compatibility is one.  Though personally I'd add toEither to Try and
  myFuture.ready(Duration.Inf).value.getOrElse(Failure(new NoSuchElementException("It is still the past"))).toEither

Maybe Daniel and Reuben have use cases where that wouldn't work?
 
2) would it suffice with a mapAll and a flatMapAll that is of the shape Try[T] => U and Try[T] => Try[U]?

That'd be a nice thing to have regardless.

  --Rex
 

Reuben Doetsch

unread,
Nov 11, 2012, 1:55:52 PM11/11/12
to scala...@googlegroups.com
@Viktor- Thanks for all the replies

Again my purpose was to bring up the proposal to remove / deprecate / rename either since I thought it was confusing name. My goal is to port an important library which I use to scala Futures 2.10 which was being blocked by the either name, since it uses a incompatible either implementation. If you look at the databinder dispatch documentation you can all see what Nathan was thinking when he created the either, left and right projections of futures.

Is there agreement that either can be removed (especially since we have Futures.awaitEither)? If so I would love to remove it in RC-3 if it is happening.

I know Daniel wants an either method on Future, but right now that is not my priority. I haven't played around with all methods enough to be %100 confident that maybe another easy solution exists. That being said here are my initial thoughts on use cases.

Possible Use Case -- 

My first thought is that transforming to eithers is useful when you have a lot of computations wrapped in Futures and you want to do pattern matching on them. Almost all of the methods on future happen async ( for a good reason). Once the future has completed (either in the positive or the negative), it is difficult to pattern match and easily extract all failures or all successes. 

Again this might be totally off and so I apologize in advance.

To give a use case of when either is nice to have.

You are doing 100 concurrent connections which encapsulate some sort of batch processing. You wait until they are all done and then want to report the status of all of them whether or not they succeeded or failed.

With either you can do the following

val i: Seq[Future[Either[Throwable, String]]] = createFutures.map(_.toEither)
val eithers: Seq[Either[Throwable,String]] = Await.ready(Futures.awaitAll(i), defaultTimeout) 

val errs = for (Left(ex) <- withers) yield
//Do something with errs
val sucs = for (Right(succ) <- eithers) yield
//Do something with successes

@Viktor - I think flatMapAll and mapAll solve this problem 

Reuben

√iktor Ҡlang

unread,
Nov 11, 2012, 1:57:28 PM11/11/12
to <scala-sips@googlegroups.com>
On Sun, Nov 11, 2012 at 7:04 PM, Rex Kerr <ich...@gmail.com> wrote:
On Sun, Nov 11, 2012 at 9:32 AM, √iktor Ҡlang <viktor...@gmail.com> wrote:
My point is:

if you are the consumer of an method that returns Future[Either[Throwable, T]], then you cannot _know_ that it won't ever be a failed Future, also, you now turn all Future error handling code that operates on Failure into a mess since you've subverted it into a Success.

Well, sure.  But it's not really any different from--in fact it's better than--

  def p(xs: List[Int]) = xs.head > 0
  val xs = (1 :: someRandomList)
  if (p(xs)) ???

I don't know that I have a nonempty list, so it's a slightly dangerous thing to do.  Not completely bulletproof.  But with adequate comments it can be an okay solution in some circumstances.

I'd advice against doing stuff like that.
 
 
A Future is already a logical Either[Throwable, T] since it wraps a Try.

Also, having a Future[Either[Throwable, T]] is a _solution_ not a _problem_/_usecase_ so we cannot even begin to offer counter-solutions.

Backwards compatibility is one.  Though personally I'd add toEither to Try and
  myFuture.ready(Duration.Inf).value.getOrElse(Failure(new NoSuchElementException("It is still the past"))).toEither

You can't call result and ready directly, you have to go thru Await.
 

Maybe Daniel and Reuben have use cases where that wouldn't work?
 
2) would it suffice with a mapAll and a flatMapAll that is of the shape Try[T] => U and Try[T] => Try[U]?

That'd be a nice thing to have regardless.

  --Rex
 

Rex Kerr

unread,
Nov 11, 2012, 2:07:39 PM11/11/12
to scala...@googlegroups.com
On Sun, Nov 11, 2012 at 1:55 PM, Reuben Doetsch <hja...@gmail.com> wrote:
With either you can do the following

val i: Seq[Future[Either[Throwable, String]]] = createFutures.map(_.toEither)
val eithers: Seq[Either[Throwable,String]] = Await.ready(Futures.awaitAll(i), defaultTimeout) 

val errs = for (Left(ex) <- withers) yield
//Do something with errs
val sucs = for (Right(succ) <- eithers) yield
//Do something with successes

val tries = eithers.flatMap(_.value)
val errs = for (Failure(ex) <- tries) yield ...
val sucs = for (Success(sc) <- tries) yield ...

  --Rex


reuben doetsch

unread,
Nov 11, 2012, 2:16:37 PM11/11/12
to scala...@googlegroups.com
Thanks Rex, I realized moments after I typed my mistake.

Another use case which viktors flatMapAll fixes is 

eithers map { 
case Left(x) => // return fixed
case Right(y) =>// return value

√iktor Ҡlang

unread,
Nov 11, 2012, 2:18:19 PM11/11/12
to <scala-sips@googlegroups.com>
This can already be done with flatMap+recoverWith AFAICT

Daniel Sobral

unread,
Nov 12, 2012, 5:39:59 AM11/12/12
to scala...@googlegroups.com
On Sun, Nov 11, 2012 at 12:32 PM, √iktor Ҡlang <viktor...@gmail.com> wrote:
My point is:

if you are the consumer of an method that returns Future[Either[Throwable, T]], then you cannot _know_ that it won't ever be a failed Future, also, you now turn all Future error handling code that operates on Failure into a mess since you've subverted it into a Success.

if you are the receiver of a method parameter of a Future[Either[Throwable, T]] then you cannot _know_ that it won't ever be a failed Future, also, you now turn all Future error handling code that operates on Failure into a mess since you've subverted it into a Success.

A Future is already a logical Either[Throwable, T] since it wraps a Try.

Also, having a Future[Either[Throwable, T]] is a _solution_ not a _problem_/_usecase_ so we cannot even begin to offer counter-solutions.

So: 

1) Why would you need Future[Either[Throwable, T]]?

As I answered before on this very list in answer to your question:

 
2) would it suffice with a mapAll and a flatMapAll that is of the shape Try[T] => U and Try[T] => Try[U]?

Cheers,



On Sun, Nov 11, 2012 at 1:52 PM, Rex Kerr <ich...@gmail.com> wrote:
On Sun, Nov 11, 2012 at 6:55 AM, √iktor Ҡlang <viktor...@gmail.com> wrote:

On Sun, Nov 11, 2012 at 2:05 AM, Derek Williams <de...@fyrie.net> wrote:

And a little bit related, and not sure if it was mentioned at all, but Future's transform method isn't very useful in it's current form (it can't turn a Future into a Future[Either[Throwable, A]], for instance).

Which I think I already proved to be impossible at the type level.

Only for a very strange definition of impossible:
  (a) It works perfectly at runtime but keeping the Future signature is not good enough, and
  (b) No alternative signature is provided, so you're out of luck!
 
  --Rex

P.S.  What is future.map(x => Right(x)).recover{ case t => Left(t) }, anyway?




--
Viktor Klang

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

Twitter: @viktorklang

√iktor Ҡlang

unread,
Nov 12, 2012, 5:59:49 AM11/12/12
to <scala-sips@googlegroups.com>
Ah, missed that email.


This one transforms turns an error result into an empty string, which 
is a good enough default for the upstream, plus log errors. 

    Http(request.HEAD OK header("Last-Modified")).either map { 
      case Right(something) => something 
      case Left(ex)         => 
        logger error "%s: erro ao verificar data de alteração: 
%s".format(request.build().getUrl, ex) 
        "" 
    } 


SIP-14: Http(request.HEAD OK header("Last-Modified")) recover { case ex => logger error "%s: erro ao verificar data de alteração: %s".format(request.build().getUrl, ex); "" }


And this one turns an error result into a None (the successful result 
is an Option), and log errors. 

        val httpResponse = Http(request.GET OK header("Last-Modified")).either 
        httpResponse.map { 
          case Right(something) => something 
          case Left(ex)         => 
            logger error "%s: erro no download: 
%s".format(request.build().getUrl, ex) 
            None 
        }.apply() 

SIP-14: Http(request.GET OK header("Last-Modified")) recover { case ex => logger error "%s: erro no download: %s".format(request.build().getUrl, ex); None }

This is similar to the above, except that the the success is not an 
Option (pun intended): 

    (db consulta DBInfo("monitoramento", "monitorado", 
None)).either.apply() match { 
      case Right(resultado) => Some(parse(resultado)) 
      case Left(ex)         => logger error "Erro ao obter municípios 
monitorados: %s".format(ex.getMessage); None 

(db consulta DBInfo("monitoramento", "monitorado", None)) map { result => Some(parse(result)) } recover { case ex => logger error "Erro ao obter municípios monitorados: %s".format(ex.getMessage); None }


The next, and final, two just produces different logging messages 
based on success/failure: 

    val respostas = urls map  { cockpitUrl => 
      cockpitUrl -> 
Http(url(cockpitUrl).POST.setBody(json).setHeader("content-type", 
"application/json") OK as.String).either 
    } 
    respostas foreach { 
      case (cockpitUrl, resposta) => 

        resposta foreach { 
          case Left(ex) => // TODO: retry? 
            logger error "%s: erro na notificação: %s (ids perdidos: 
%s)".format(cockpitUrl, ex, ids mkString ", ") 
          case _        => 
            logger trace "Notificado %s com %s".format(cockpitUrl, ids 
mkString ", ") 
        } 
    } 

        val resultadoDaPersistencia = (db insere (dbInfo, dadosAGravar)).either 

        resultadoDaPersistencia foreach { 
          case Right(_) => 
            logger trace "Persistido %s/%s/%s".format(dbInfo.indice, 
dbInfo.tipo, dbInfo.id getOrElse "") 
          case Left(ex) => 
            logger error "Falha ao persistir 
%s/%s/%s!".format(dbInfo.indice, dbInfo.tipo, dbInfo.id getOrElse "") 
        } 


That was a bit too much noise, so just extrapolate from the code presented previously.


Cheers,

Daniel Sobral

unread,
Nov 15, 2012, 12:11:15 PM11/15/12
to scala...@googlegroups.com
This changes the semantic, making it incorrect.
 


The next, and final, two just produces different logging messages 
based on success/failure: 

    val respostas = urls map  { cockpitUrl => 
      cockpitUrl -> 
Http(url(cockpitUrl).POST.setBody(json).setHeader("content-type", 
"application/json") OK as.String).either 
    } 
    respostas foreach { 
      case (cockpitUrl, resposta) => 

        resposta foreach { 
          case Left(ex) => // TODO: retry? 
            logger error "%s: erro na notificação: %s (ids perdidos: 
%s)".format(cockpitUrl, ex, ids mkString ", ") 
          case _        => 
            logger trace "Notificado %s com %s".format(cockpitUrl, ids 
mkString ", ") 
        } 
    } 

        val resultadoDaPersistencia = (db insere (dbInfo, dadosAGravar)).either 

        resultadoDaPersistencia foreach { 
          case Right(_) => 
            logger trace "Persistido %s/%s/%s".format(dbInfo.indice, 
dbInfo.tipo, dbInfo.id getOrElse "") 
          case Left(ex) => 
            logger error "Falha ao persistir 
%s/%s/%s!".format(dbInfo.indice, dbInfo.tipo, dbInfo.id getOrElse "") 
        } 


That was a bit too much noise, so just extrapolate from the code presented previously.

Well, all the other ones were map, this one is foreach. You can't recover from a foreach, because it doesn't return a Future, and I'm not about to call map on a Future for the side effect.

To sum it up, you propose I replace this:

x.either match {
  case Right(x) => f(x)
  case Left(x)   => g(x)
}

into this:

x map {
  case x => f(x)
} recover {
  case x => g(x)
}

That has a different semantic, it's longer, it chains things as if there's one value that is modified twice instead of making it clear that there's one value that has two different treatments, and, of course, it ignores Either, which has been around for a long time.

So, no, it's not a replacement.

Rex Kerr

unread,
Nov 15, 2012, 12:52:01 PM11/15/12
to scala...@googlegroups.com
onComplete {
  case Success(x) => f(x)
  case Failure(x) => g(x)
}?

  --Rex


On Thu, Nov 15, 2012 at 12:11 PM, Daniel Sobral <dcso...@gmail.com> wrote:
On Mon, Nov 12, 2012 at 8:59 AM, √iktor Ҡlang <viktor...@gmail.com> wrote:
Ah, missed that email.



That was a bit too much noise, so just extrapolate from the code presented previously.

√iktor Ҡlang

unread,
Nov 15, 2012, 1:32:25 PM11/15/12
to <scala-sips@googlegroups.com>
On Thu, Nov 15, 2012 at 6:52 PM, Rex Kerr <ich...@gmail.com> wrote:
onComplete {
  case Success(x) => f(x)
  case Failure(x) => g(x)
}?


If all you're going to do is side-effect, +1 for what Rex said.

Daniel Sobral

unread,
Nov 18, 2012, 2:02:48 PM11/18/12
to scala...@googlegroups.com
Ok, that works. I assumed "onComplete" only worked for success.

Daniel Sobral

unread,
Nov 19, 2012, 1:35:57 PM11/19/12
to scala...@googlegroups.com
Actually, no. I just realized that onComplete returns Unit. It serves where I just want to handle the logging, but it doesn't work when I want to map successes to one thing and failures to another. map/recover doesn't work for that because it's not the same semantic, and it splits one logical block in two (which I actually find the be the worse problem).

So, still no replacement.

Rex Kerr

unread,
Nov 19, 2012, 1:40:03 PM11/19/12
to scala...@googlegroups.com
.value.map(_ match {
  case Success(s) => f(s)
  case Failure(t) => g(t)
})

?

  --Rex

Daniel Sobral

unread,
Nov 19, 2012, 1:41:30 PM11/19/12
to scala...@googlegroups.com
And that led me to finally understand what bothers me about the API. It specializes error handling through methods: you pick a different method depending on whether you want to handle success or failure. I want to handle errors through data: turn the possibility of error into a value, and then use the same standard methods for both error and success.

No wonder I miss Either.

Daniel Sobral

unread,
Nov 19, 2012, 1:42:56 PM11/19/12
to scala...@googlegroups.com
On Mon, Nov 19, 2012 at 4:40 PM, Rex Kerr <ich...@gmail.com> wrote:
.value.map(_ match {
  case Success(s) => f(s)
  case Failure(t) => g(t)
})

?

If I didn't want to stay asynchronous, I wouldn't be using Future in first place.

Derek Williams

unread,
Nov 19, 2012, 7:08:05 PM11/19/12
to scala...@googlegroups.com
What you want is probably the equivalent of Try's transform method (not to be confused with Future's transform):

def transform[U](s: (T) ⇒ Try[U], f: (Throwable) ⇒ Try[U]): Try[U]
--
Derek Williams

Derek Williams

unread,
Nov 19, 2012, 7:26:01 PM11/19/12
to scala...@googlegroups.com
Sorry, reread your post again, not quite what you want. a method (Try[T] => Future[U]): Future[U] or (Try[T] => U): Future[U] would probably work better. Simple to implement (should compile, not tested):

implicit class FutureW[T](val underlying: Future[T]) extends AnyVal {

  def myFlatMap[U](f: Try[T] => Future[U])(implicit executionContext: ExecutionContext): Future[U] = {
    val promise = Promise[U]()
    underlying onComplete { x =>
      promise completeWith {
        try { f(x) } catch { case e if NonFatal(e) => Future failed e }
      }
    }
    promise.future
  }

  def myMap[U](f: Try[T] => U)(implicit executionContext: ExecutionContext): Future[U] = {
    val promise = Promise[U]()
    underlying onComplete { x =>
      promise complete Try(f(x))
    }
    promise.future
  }

  // or perhaps this one? could also return Future[Either[Throwable, T]]
  def liftTry(implicit executionContext: ExecutionContext): Future[Try[T]] = {
    val promise = Promise[Try[T]]()
    underlying onComplete (promise success)
    promise.future
  }

}
--
Derek Williams

reuben doetsch

unread,
Nov 19, 2012, 7:31:23 PM11/19/12
to scala...@googlegroups.com
Great solution Derek thanks!

Anyone have any knowledge about the RC-3 coming out and is either going to be removed or renamed?

Reuben

√iktor Ҡlang

unread,
Nov 21, 2012, 4:20:55 AM11/21/12
to <scala-sips@googlegroups.com>
Well, first it needs to be decided.

Who are in favor of removing it?
Who have good alternate names for it?

Josh Suereth

unread,
Nov 21, 2012, 7:35:14 AM11/21/12
to scala...@googlegroups.com
Sorry I've been delayed in reading this thread fully.   Given the debate over this API and my opinion that it's better to release 2.10.0 without a questionable method and add the right one later,   Here's what we're doing for 2.10.0-RC3:

* The method `either` is removed

I encourage everyone on this discussion to think through a good proposal for what to do w/ Futures in 2.10.1.   We have until the end of December to make a decision before new methods will no longer be allowed in the library and you'll have to wait for 2.10.2.

√iktor Ҡlang

unread,
Nov 21, 2012, 7:47:31 AM11/21/12
to <scala-sips@googlegroups.com>
*applause*!

Thanks Josh,

Philipp Haller

unread,
Nov 21, 2012, 8:26:16 AM11/21/12
to scala...@googlegroups.com
Yep, thanks, Josh!

Philipp

Daniel Sobral

unread,
Nov 22, 2012, 10:45:09 AM11/22/12
to scala...@googlegroups.com
On Wed, Nov 21, 2012 at 10:35 AM, Josh Suereth <joshua....@gmail.com> wrote:
Sorry I've been delayed in reading this thread fully.   Given the debate over this API and my opinion that it's better to release 2.10.0 without a questionable method and add the right one later,   Here's what we're doing for 2.10.0-RC3:

* The method `either` is removed

I encourage everyone on this discussion to think through a good proposal for what to do w/ Futures in 2.10.1.   We have until the end of December to make a decision before new methods will no longer be allowed in the library and you'll have to wait for 2.10.2.

Personally, I'm all for waiting until 2.10.2. Let people use it, and see what's missing.

Piyush Purang

unread,
Apr 22, 2013, 10:15:14 AM4/22/13
to scala...@googlegroups.com
Is this issue solved or did it once again go off the radar? Is it being discussed/tracked some place else?

√iktor Ҡlang

unread,
Apr 22, 2013, 10:41:37 AM4/22/13
to <scala-sips@googlegroups.com>
"either" you mean?


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



--
Viktor Klang
Director of Engineering

Twitter: @viktorklang

Piyush Purang

unread,
Apr 22, 2013, 1:03:51 PM4/22/13
to scala...@googlegroups.com
yes, even though the name is disputed :)

√iktor Ҡlang

unread,
Apr 22, 2013, 1:49:07 PM4/22/13
to <scala-sips@googlegroups.com>
I think there was consensus in removing it.

Or did I miss something?

I've got a couple of suggestions going (some of them bugfixes that already made it into 2.10.1 and 2.11.x) over here: https://github.com/viktorklang/scala/commits/wip-sip14-bugfixes-%E2%88%9A

Cheers,
Reply all
Reply to author
Forward
0 new messages