FunFunFunction Video: Reduce advanced - Part 4 of Functional Programming in JavaScript

(This post is part of the F3C series)

Reduce is powerful, much more than its siblings. You can use it not only to sum values (the classic “hello world” example for reduce), but also to build up a complex end result that may look nothing like what you started with, i.e. the list you are calling reduce upon. It’s a mistake to think of reduce in terms of what that word means in English; you’re not necessarily making something smaller than what you started with, you can make pretty much anything, of any size1.

As well as function composition (slotting functions into each other), another common style in functional programming is function chaining. The binding together of small functions that operate on data one after the other1.

The example that MPJ uses in this video is a good illustration of chaining. Aside from the call to console.log, the entire program is a single statement - an assignment of a value to the output variable:

var output = fs.readFileSync('data.txt', 'utf8')
  .trim()
  .split('\n')
  .map(line => line.split('\t'))
  .reduce((customers, line) => {
    ...
  }, {})

What MPJ doesn’t say explicitly, but is one of the reasons why this approach is so powerful and simple, is that each of these functions take input, and produce new output. There’s no mutation of state. This means that there is less to go wrong. Further, apart from trim, all functions produce or operate on lists:

split operates on a string and produces a list map operates on a list and produces another list reduce operates on a list and produces … well, whatever you want

Notice that this part: map(line => line.split('\t')) actually produces a list … of lists.

  1. This reminds me of the Unix philosophy of small programs doing one thing well, connected and passing data via a series of pipes.  2