Fold is a functional programming pattern that operates over some sequence with a binary operation and a starting value. There are two variants:
FoldLeft: Performs the binary operation from the left of the sequence to the right.
```scala
List(1, 2, 3, 4).foldLeft(0)(_ + _)
// ((((0 + 1) + 2) + 3) + 4)
// 10
```
FoldRight: Performs the binary operation from the right of the sequence to the left.
```scala
List(1, 2, 3, 4).foldRight(0)(_ + _)
// (1 + (2 + (3 + (4 + 0))))
// 10
```
The two fold variants only return the same solution if the function being applied is associative. Which is the case for integer addition above.
## Definition and the Two Views
Definition of `foldLeft` within Scala:
```scala
def foldLeft[B](z: B)(op: (B, A) => B): B = this match {
case seq: IndexedSeq[A @unchecked] => foldl(seq, 0, z, op)
case _ =>
var result = z
val it = iterator
while (it.hasNext) {
result = op(result, it.next())
}
result
}
def foldl[B](seq: IndexedSeq[A], start: Int, z: B, op: (B, A) => B): B = {
@tailrec def loop(at: Int, end: Int, acc: B): B =
if (at == end) acc
else loop(at + 1, end, op(acc, seq(at)))
loop(start, seq.length, z)
}
```
Notice that this includes both a recursive and iterative definition within one function! Since most people start off by learning loops, let's focus on the iterative implementation.
```scala
var result = z
while (it.hasNext) {
result = op(result, it.next())
}
```
## Combining Folds
When building out complex functions we may want to loop multiple times:
- While loops next to each other ($n_1 + n_2$ complexity)
- While loop within a while loop ($n_1 * n_2$ complexity)