Comparing scala.concurrent.Future's for Equality

601 views
Skip to first unread message

Kevin Meredith

unread,
Aug 29, 2015, 11:30:53 PM8/29/15
to scala-user

Why does the following equality comparison result in false?


$scala

Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_51).


scala> import scala.concurrent.Future

import scala.concurrent.Future


scala> Future.successful(5) == Future.successful(5)

res4: Boolean = false



Nils Kilden-Pedersen

unread,
Aug 30, 2015, 12:13:42 AM8/30/15
to Kevin Meredith, scala-user
Probably because a Future is stateful, thus any such comparison is inherently indeterministic.



--
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/d/optout.

Viktor Klang

unread,
Aug 30, 2015, 7:36:11 AM8/30/15
to Nils Kilden-Pedersen, Kevin Meredith, scala-user
Nils is on the right track, but it's not due to its statefulness (already completed Futures are immutable values), it is due to the temporal aspect of Futures.
--
Cheers,

Kevin Wright

unread,
Aug 30, 2015, 7:48:55 AM8/30/15
to Viktor Klang, Nils Kilden-Pedersen, Kevin Meredith, scala-user
Expanding on that, the only valid comparison between Futures would itself be asynchronous, so you're looking for a Future[Boolean]

As in...

val fa = Future successful 5
val fb = Future successful 5

val result = for(a <- fa; b <- fb) yield a == b

or

val result = fa flatMap {a => fb map (a == _) }


Personally, I prefer the first form... though it could be argued that it's a tiny bit less efficient

Viktor Klang

unread,
Aug 30, 2015, 7:58:52 AM8/30/15
to Kevin Wright, Nils Kilden-Pedersen, Kevin Meredith, scala-user
On Sun, Aug 30, 2015 at 1:48 PM, Kevin Wright <kev.lee...@gmail.com> wrote:
Expanding on that, the only valid comparison between Futures would itself be asynchronous, so you're looking for a Future[Boolean]

As in...

val fa = Future successful 5
val fb = Future successful 5

val result = for(a <- fa; b <- fb) yield a == b

or

val result = fa flatMap {a => fb map (a == _) }


Personally, I prefer the first form... though it could be argued that it's a tiny bit less efficient

Also, note that the above doesn't consider failed Futures with equal exceptions as equal.
 


On 30 August 2015 at 12:35, Viktor Klang <viktor...@gmail.com> wrote:
Nils is on the right track, but it's not due to its statefulness (already completed Futures are immutable values), it is due to the temporal aspect of Futures.

On Sun, Aug 30, 2015 at 6:12 AM, Nils Kilden-Pedersen <nil...@gmail.com> wrote:
Probably because a Future is stateful, thus any such comparison is inherently indeterministic.



On Sat, Aug 29, 2015 at 10:30 PM, Kevin Meredith <kevin.m....@gmail.com> wrote:

Why does the following equality comparison result in false?


$scala

Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_51).


scala> import scala.concurrent.Future

import scala.concurrent.Future


scala> Future.successful(5) == Future.successful(5)

res4: Boolean = false






--
Cheers,

Kevin Wright

unread,
Aug 30, 2015, 8:11:07 AM8/30/15
to Viktor Klang, Nils Kilden-Pedersen, Kevin Meredith, scala-user
On 30 August 2015 at 12:58, Viktor Klang <viktor...@gmail.com> wrote:


On Sun, Aug 30, 2015 at 1:48 PM, Kevin Wright <kev.lee...@gmail.com> wrote:
Expanding on that, the only valid comparison between Futures would itself be asynchronous, so you're looking for a Future[Boolean]

As in...

val fa = Future successful 5
val fb = Future successful 5

val result = for(a <- fa; b <- fb) yield a == b

or

val result = fa flatMap {a => fb map (a == _) }


Personally, I prefer the first form... though it could be argued that it's a tiny bit less efficient

Also, note that the above doesn't consider failed Futures with equal exceptions as equal.
 

It's simple enough to turn a Future[T] into a Future[Try[T]] and guarantee that it will *always* be a successful future.

Of course, the catch then is that there's no guarantee that any exception will have a sane definition of equality.

Oliver Ruebenacker

unread,
Aug 30, 2015, 9:54:34 AM8/30/15
to Kevin Wright, Viktor Klang, Nils Kilden-Pedersen, Kevin Meredith, scala-user

     Hello,

  Scala Shell has an opinion on the equality of Exceptions:

scala> val message = "Boom!"
message: String = Boom!

scala> new Exception(message) == new Exception(message)
<console>:12: warning: comparing a fresh object using `==' will always yield false
       new Exception(message) == new Exception(message)
                              ^
res0: Boolean = false

 Of course, Scala Shell also knows that this is not true for all "fresh objects":

scala> case class A(i:Int)
defined class A

scala> new A(1) == new A(1)
res1: Boolean = true

  What Scala Shell really means is that Exception uses the same equality as Object, which is object identity.

  The lesson is: expect equality to be object identity, unless you have evidence to the contrary.

     Best, Oliver
 

--
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/d/optout.



--
Oliver Ruebenacker
Senior Software Engineer, Diabetes Portal, Broad Institute

Reply all
Reply to author
Forward
0 new messages