In the coursera course Functional Reactive Programming Week 3 Lecture 4 Erik Meijer implements a retry function for a Future, which will retry a computation a given number of times. He specfies block
as a call_by_name parameter since the Future should be evaluated on each retry and not only once.
def retry(noTimes: Int)(block: =>Future[T]): Future[T] = {
if (noTimes == 0) {
Future.failed(new Exception(“Sorry”))
} else {
block fallbackTo {
retry(noTimes–1) { block }
}
}
}
My Question is: Since block
is already call_by_name parameter, is it necessary to wrap it into a block on calling it or is it just for readability reasons?
retry(noTimes–1) { block }
//same as?
retry(noTimes–1)(block)
Same question with fallbackTo
def fallbackTo(that: =>Future[T]): Future[T] = {
this recoverWith {
case _ => that recoverWith { case _ ⇒ this }
}
fallbackTo { retry(noTimes–1) { block } }
//same as?
fallbackTo ( retry(noTimes–1)(block) )
No, it isn't required to put them into curly braces. It is your choice and I guess Erik has chosen curly braces because that is the way the function will be called typically. As soon as you multiple statements you will have to use curly braces, because parentheses are just for single expressions.
In the recursive call there is only one expression (namely block
) so you can leave the curly braces if you want to. Doen't make any difference.
To throw in some trustworthy reference: In Martin Odersky's Scala by Example on page 6 you will find an example of call by name parameters in a very similar use case but without curly braces:
def While (p: => Boolean) (s: => Unit) {
if (p) { s ; While(p)(s) }
}