# How reduceLeft works on sequence of Functions returning Future

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.

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