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)
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.
ChrisOn 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,√
What happens if the Future[Either[Exception, T]] is failed?
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.
contains a Failure instead of a Success
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"?
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.
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))
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 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> future2val firstOf = future firstCompletedOf future2 //Clashes with Future.firstCompletedOf and is also quite unpleasant visuallyval firstOf = future race future2val firstOf = future || future2 // doesn't have the right semantics, people expect short-circuitPerhaps the right solution is to remove the method?
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> future2val firstOf = future firstCompletedOf future2 //Clashes with Future.firstCompletedOf and is also quite unpleasant visuallyval firstOf = future race future2val firstOf = future || future2 // doesn't have the right semantics, people expect short-circuitPerhaps 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.
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
val firstOf = future || future2 // doesn't have the right semantics, people expect short-circuit
The only option I see is to remove it completely in the next Scala 2.10 RC (if there is another one).
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.
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.
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.
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
P.S. I prefer not using "either" to mean "or". For example: we could rename this method either remove it entirely. Huh?!
That was exactly my point.
>
> --Rex
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?
--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).ThanksReuben
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
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.
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.
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.
2) would it suffice with a mapAll and a flatMapAll that is of the shape Try[T] => U and Try[T] => Try[U]?
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
With either you can do the followingval 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 errsval sucs = for (Right(succ) <- eithers) yield//Do something with successes
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,√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
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.
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.
onComplete {
case Success(x) => f(x)
case Failure(x) => g(x)
}?
.value.map(_ match {
case Success(s) => f(s)
case Failure(t) => g(t)
})
?
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 removedI 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.
--
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.