Loops using fold – Practical Functional Programming | Part 4

Sandro Maglione

Sandro Maglione

Functional programming

Loops using fold. In functional programming we do not use almost any for or while. Instead of writing loops using imperative instructions, in functional programming you have a series of functions that allows you to loop over collections.

The most flexible and used of these functions is called fold (foldl, foldLeft, reduce).

In this article, we are going to learn how to implement loops using fold in functional programming.

Practical Functional Programming step by step is a series in which we are going to uncover the principles of functional programming and effective coding one small piece at the time.

Starting from a complete code example, we are going to learn step by step what makes a good functional code and what are the benefits of applying a functional programming paradigm to your codebase.


Why you do not need loops

If you are used to write imperative code, you may consider for, while, forEach as one of the main constructs in your codebase. These constructs are the first one to which you are introduced when you start learning about code and programming.

Nonetheless, these constructs are not generally safe nor required. They relay on you to implement all the details behind your algorithm in an imperative manner.

When you use a for loop, you must take care of initialising all the variables, updating their values every cycle, paying attention to every detail. This makes you code difficult to read and error prone.

Remember then, you do not need loops. Not at all. If you are not convinced, take a look here for an extensive dive deep into the subject.

Loops using fold in Functional Programming

What to do instead of loops?

There are be many ways of implementing loops. In this article we are going to explore the fold function.

The fold function works exactly like a for loop over a collection. It takes the elements of the collection one by one and lets you do some operation on these values.

Let's look at our code example:

Map<String, int> buildmap(String str) => str.split('').foldLeft(
      <String, int>{},
      (acc, x) => {
        ...acc,
        x: (acc[x] ?? 0) + 1,
      },
    );

In the buildmap function, we are using foldLeft. This function allows us to cycle over all the letters of the source string and accumulate them in one final value.

The first parameter is the initial value of the accumulator (and empty Map). Then, for each element in the collection, foldLeft will call the second function provided, passing the accumulator and the values in the collection.

By using foldLeft, we convert a List into a Map. This same function could be rewritten imperatively as follows:

Map<String, int> buildmap(String str) {
  var acc = <String, int>{};
  var list = str.split('');
 
  for (var i = 0; i < list.length; ++i) {
    final x = list[i];
    acc[x] = (acc[x] ?? 0) + 1;
  }
 
  return acc;
}

As you can see, using imperative programming you are required to take care of every detail in the implementation. Using fold instead, you only need to provide what's necessary; Namely the initial value and the accumulator function!


You should now have a more clear idea of why loops are (generally) bad and how you can do without them. fold can be used to implement a great variety of other functions (map, zip, filter). Once you understand how fold works, you have a powerful tool at your disposal!

See you on Part 5!

👋・Interested in learning more, every week?

Every week I build a new open source project, with a new language or library, and teach you how I did it, what I learned, and how you can do the same. Join me and other 600+ readers.