I am going through the Principels of Reactive Programming course at Coursera and noticed few times a notation which I cannot completely comprehend. So I hope you can help me to understand. Here is the code snippet:
def retry(noTimes:Int)(block: => Future[T]): Future[T] = {
val ns: Iterator[Int] = (1 to noTimes).iterator
val attempts: Iterator[Future[T]] = ns.map(_ => () => block)
val failed = Future.failed(new Exception)
attempts.foldLeft(failed) ((a, block) => a recoverWith {block()})
}
It is not clear to me why in the attempts value definition it is not simply ns.map(_ => block) ?
Type of the attempts value is Iterator[Future[T]] and map as it written in the snippet seems to me should produce Iterator[() => Future[T]]. Could you help to grasp it?
With this:
ns.map(_ => block)
block would be executed directly, that's not what the author would want.
Similar to Call-By-Value parameter.
However, with this:
ns.map(_ => () => block), it is similar to Call-By-Name parameter, meaning that the block code would be executed only when explicitly called in the underlying function.
If I correctly remembered, the author of the course was saying something like:
"Sit down, take a coffee and deeply analyse the function in order to figure out why we need to execute the block code lazily" ;)
UPDATE-------
In the wrapping method's signature, block is declared as a call-by-name parameter:
block: => Future[T]
Therefore, the Future[T] well corresponds to () => block explaining why:
val attempts: Iterator[Future[T]] is not val attempts: Iterator[() => Future[T]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With