This might be a naive question and I am sorry for that. I am studying Scala Futures and stumbled on below code:

```
object Main extends App {
def await[T](f: Future[T]) = Await.result(f, 10.seconds)
def f(n: Int): Future[Int] = Future {n + 1}
def g(n: Int): Future[Int] = Future {n * 2}
def h(n: Int): Future[Int] = Future {n - 1}
def doAllInOrder[T](f: (T => Future[T])*): T => Future[T] = {
f.reduceLeft((a,b) => x => a(x).flatMap(y => b(y)))
}
println(await(doAllInOrder(f, g, h)(10))) // 21
}
```

I know how `reduceLeft`

works when it is applied on `Collections`

. But in the above example, as I understand, in the first pass of `reduceLeft`

value `x`

i.e. `10`

is applied to Function `a`

and the result is applied to Function `b`

using `flatMap`

which eventually return `Future[Int]`

(say, I call it `result`

). In the next pass of `reduceLeft`

the `result`

and Function `h`

has to be used, but here is I am troubled.

The `result`

is actually an already executed Future, but the `reduceLeft`

next pass expects a Function which returns a Future[Int].Then how it is working?

Another thing I am not able to understand how each pass sending its result to next pass of `reduceLeft`

, i.e. how `x`

is getting itâ€™s value in subsequent passes.

Though both of my confusions are interrelated and a good explanation may help clear my doubt.

Thanks in advance.

I would recommend you to execute the algorithm by hand on a paper or whiteboard.

You are right that `reduceLeft`

expects the result to be of the same type as the elements over which we are reducing. Also, the `doAllInOrder`

function has a return type of `T => Future[T]`

.

Where you are wrong is the assumption, that the result of the first pass is an executed future. Here is the same function, but with more indentation and type annotations:

```
def doAllInOrder[T](f: (T => Future[T])*): T => Future[T] = {
f.reduceLeft(
(a: (T => Future[T]) ,b: (T => Future[T])) =>
(x: T) => a(x).flatMap(y => b(y)) //this whole line returned
)
}
```

So the `x`

does not have a value here (where should it come from? our doAllInOrder function doesnâ€™t have a value of type T). Instead it is the parameter of a new lambda, which is the result of type `T => Future[T]`

. Itâ€™s easy to overlook, because it is nested in another lambda (the one passed to reduceLeft).

So `doAllInOrder`

combines the functions, the result of the reduceLeft *is a function*. Passing 10 happens here after that method has already finished, while all the `flatMaps`

only happen, after the combined function receives that value.

It is basically the same as function composition without Future:

```
def doAllInOrder[T](f: (T => T)*): T => T = {
f.reduceLeft((a,b) => x => b(a(x)))
// or f.reduceLeft((a,b) => a andThen b)
}
```

1 Like

The other thing to keep in mind is that you basically should never think of Future in terms of â€śalready executedâ€ť. You know that a Future is already *started*, which is a very different thing.

The way you work with Futures is that youâ€™re always saying, â€śWhen this Future is done, do this next thingâ€ť â€“ thatâ€™s what `map`

and `flatMap`

do. So this `reduceLeft`

is basically defining a chain of executions, where one finishing will produce a result, that allows the next step to begin.

1 Like