Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boolean logic in Future[Boolean]

In non-concurrent programming, we usually have this kind of boolean logic:

boolean canIMarryher(){
    return iLoveHer() && myParentsLoveHer() && shesHot() && sheSaidYes();
}

Here comes my question, what if all these(or some of these conditions) are Future[Boolean] in scala? Can I still get a clear method just like the example above?

Update As you know, in boolean logic at run time we'll have 'optimization' like: immediately return when using && and met a false or using || and met a true. Can I have it in Future[Boolean] as well?

Regards, Drew

like image 314
noru Avatar asked Sep 05 '15 15:09

noru


2 Answers

The other answers with for-comprehension and reduce will not "short-circuit." That is, if the first future takes a while to complete, we will wait that whole time even if the second future evaluates false immediately.

To clarify, this is different from short-circuiting in traditional boolean logic where we evaluate the right-hand side of the operator by-name. Instead, the goal is to produce the answer as fast as possible. We start every future's computation immediately, and short-circuit if possible as the results come in. In the best case, we only have to wait for the fastest future, and in the worst case, we have to wait for the slowest future.

Here's a method which supports this type of short-circuiting:

def all(futures: Future[Boolean]*)(implicit executor: ExecutionContext): Future[Boolean] = {
  Future.find(futures) { !_ } map { _.isEmpty }
}

def canIMarryher = all(iLoveHer, myParentsLoveHer, shesHot, sheSaidYes)

If you really wanted to, you could take the idea further and define && and || methods for Future[Boolean]

like image 194
dwickern Avatar answered Sep 21 '22 15:09

dwickern


As math said, Future.reduce is good if you can see them as a sequence of values, if you need to stick more meaning to each of them you can use a for comprehension:

val isThereAFuture: Future[Boolean] = 
  for {
    iLoveHer <- doILoveHer()
    myParentsLoveHer <- doMyParentsLoveHer()
    sheLovesMe <- doesSheLoveMe()
  } yield iLoveHer && myParentsLoveHer && sheLovesMe
like image 34
johanandren Avatar answered Sep 22 '22 15:09

johanandren