Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we need both Future and Promise?

As I know, Future is read-only and Promise is write-once data structure.

We need a Promise to complete a Future

For example,

object Lie extends Throwable

val lie = Future { throw Lie } 

val guess = Promise[String]()     

lie.onComplete { case Success(s) => guess.success("I knew it was true!") 
                 case Failure(t) => guess.failure("I knew it was lie")} 
// return type: Unit 

guess.future.map(println) 
// res12: scala.concurrent.Future[Unit] = List()
// I knew it was lie!
// Requires Promise to chain Future with exception 


But, I can't understand why we need to have both Future and Promise

I guess Promise is required because of Future.onComplete signature

Since Future.onComplete return type is Unit,Future with possible exceptions cannot be chained

I assume Promise was introduced to overcome this limitation


But why not just change the signature of Future.onComplete ?

Changing the return type of Future.onComplete as Future[T] will enable chaining on Future with exception

and then, Future does not need Promise

For example, code above can be changed into

val lie = Future { throw Lie } 

lie.onComplete { 
   case Success(s) => "I knew it was true!"
   case Failure(t) => "I knew it was lie!"
}.map(println) 

//onComplete return type is Future[String]


My question is

1) am I right? does Future not need Promise , If onComplete signature is changed from Unit to Future[T]?

2) Why Future and Promise are divided in the first place ?

UDPATE

Thanks to the repliers, Now I understand the purpose of Promise. It wasn't actually for Future chaining

If I may, can I ask you

Why onComplete returns Unit ??

It can actually return Future[T] to enable chaining Future easily

For example

Future { throw Error }.onComplete {
  case Success(s) => "Success" 
  case Failure(t) => throw Error
}.onComplete {
  case Success(s) => "Success"
  case Failure(t) => throw Error 
}. ... 
like image 333
Wonpyo Park Avatar asked Oct 30 '16 17:10

Wonpyo Park


People also ask

Are futures and promises the same?

Specifically, when usage is distinguished, a future is a read-only placeholder view of a variable, while a promise is a writable, single assignment container which sets the value of the future.

What is the use of future and promise in C++?

future is the object that is typically associated with the shared object on the consumer side. A promise is an object that can store the object which is to be shared by the producer. This shared object is typically retrieved into a future object. promise offers a synchronization mechanism on the producer side.

What is a promise in computing?

In programming, Promise means that a program calls a function in the anticipation that it will do some useful thing and return the result which calling program can use. The result or promise is the outcome of calling the function which can be a success or a failure, and the data associated with it.

What is STD promise?

The class template std::promise provides a facility to store a value or an exception that is later acquired asynchronously via a std::future object created by the std::promise object.


2 Answers

Future.apply[T](block: => T): Future[T] is syntactic sugar for Future.unit.map(_ => block)[1]

A Future represents a value which may or may not be currently available.

A Promise represents the obligation to provide such a value at some point.

Having separate entities for Future (for reads) and Promise (for writes) means that it is easy to reason about capabilities:

  • When a Future is a parameter, it is a request to have some value at some point and when it is used as a return type, it's a response which may not be currently available.

  • When a Promise is a parameter, it is the "consumption" of responsibility of producing some value at some point, and when it is used as a return type it is the "production" of responsibility to produce the value at some point.

All in all, being able to reason about capabilities, especially in asynchronous, or even concurrent programs, is extremely valuable.

Most of the time Promises need not be used, since that is transparently handled by the Future-combinators—but when integrating with third party software or networking libraries it can be extremely useful.

For more information about interesting new features in Scala 2.12, have a look here.

1: Where Future.unit is defined as: val unit: Future[Unit] = Future.successful(())

like image 50
Viktor Klang Avatar answered Oct 06 '22 01:10

Viktor Klang


am I right? does Future not need Promise , If onComplete signature is changed from Unit to Future[T]?

You're mixing things up a little. Let's clarify.

A Future[T] represents a computation which will complete in the future. That is, you pass Future.apply a function which will execute on a thread assigned by some ExecutionContext you define.

Now, on the other hand, a Promise[T] is a way to create a Future[T], without actually creating a Future[T]. A good example for this would be the Future.successful method (which will internally consume Promise.successful):

def successful[T](result: T): Future[T] = Promise.successful(result).future

This requires no ExecutionContext and no queuing if any additional resources. It's merely a convenience wrapper that allows you to "artificially" create a Future[T].

like image 23
Yuval Itzchakov Avatar answered Oct 06 '22 00:10

Yuval Itzchakov