Search code examples
scalasyntaxsemantics

Scala - Passing a function to Future.apply


I'm learning Scala and just getting familiar with syntax. I see that Future.apply takes a function as the work to do.

The following works perfectly:

val future = Future { doWork(1) }

However just for experimentation I tried some other ways to do it, and neither work appropriately.

val future = Future(() => doWork(1))

This results in the lambda becoming the completion value of the future, instead of the return value of doWork(1).

val work: () => Int = () => doWork(index)
val future = Future(work)

The same situation here. Could someone explain why passing the function as the work to be done is instead resulting in the function actually becoming the return value of the work being done. Also how would I go about this. Thanks!


Solution

  • The signature of method called in Future {...} is def apply[T](body: =>T) where => T is a by-name parameter. See this documentation for more info.

    By-name parameters are only evaluated when used.

    In examples

    Future(() => doWork(1)) 
    

    and

    val work: () => Int = () => doWork(index)
    val future = Future(work)
    

    You are passing as by-name parameter function of type () => Int or same as Function0[Int]. This function is returned in the Future when by-name parameter is evaluated.

    The function is not evaluated as Future does not call apply or ().

    It will be more understandable if you add type parameters to the Future in all examples. If doWork returns Int. In this case Future { doWork(1) } is Future[Int] whereas it is Future[Function0[Int]] in the second and third examples.

    The correct usage would be

    val work: () => Int = () => doWork(index)
    val future = Future(work())