Title slide for “Reducing Enumerable — An Illustrated Adventure”

Behold! The lemurs have chosen to appear on a text-based medium, bringing with them the entirety of the illustrated content from “Reducing Enumerable — An Illustrated Adventure”.

If you wish to see the full RubyConf version of the talk, you can find it here:

As this was a very image intensive and story driven presentation, we’ll be splitting this up into multiple articles for the sake of digestibility.

Table of Contents

Next >>

Meet Red

Red waving hi

Meet Red, the lemur. He’s a student of the great Master Scarlet, learning the ways of reduce.

He’s been practicing for quite some time now on summing numbers and learning the ways of functional programming.

By this point he believes himself to be quite adept at it, if not ready to attempt the mastership trials himself.

Red with a hammer, thinking about reducing things

Now Red absolutely adores reduce, and especially reducing large stacks of numbers into simple sums. He’s gotten quite good at it in fact.

Red dreaming about reducing big stacks of numbers

So good in fact that he’s become rather obsessed with it, and he’d like to show us the basics of how reduce works. Shall we take a look?

A Look into Reduce

Now reduce is a very interesting function in Enumerable, and very frequently it’s hard to understand what it’s doing.

Let’s take a bit of a look into how it works.

list of 1, 2, and 3 sums to 6

Reduce, in the case of a sum, takes in a list of numbers and returns back the sum of those numbers.

[1,2,3].reduce(0) { |a, v| a + v } # => 6

The code for this might look something like this, but that’s a bit hard to understand, so let’s break it down a bit, shall we?

Accumulators

Looking at the accumulator, 0, represented as a in the function and returned with the value 6

We start with an accumulator. An accumulator starts as the first argument to reduce, and in this case it’s 0 . Why 0 ? If we add anything to 0 we get back that number. That makes it a good “empty” element.

When the list is empty we get back our empty element!

We’ll see our accumulator show up as a throughout this article.

Lists and Values

Looking at the list of 1, 2, and 3 represented as v in the function

Next up is our list, which will show up as v throughout this article. Every element of our list will be iterated over while reducing, going into the function as v .

Joining Values and Accumulators

Looking at the plus operator used to join an accumulator and a value to make a new accumulator

Last, and perhaps most importantly is how we join our value and our accumulator together to make a new accumulator. In this case, + .

Now the interesting thing here is that how we join things together impacts our empty value as well. It would make very little sense to join any number with multiplication if our supposedly empty value is 0 , no?:

[1, 2, 3].reduce(0) { |a, v| a * v }

=> 0

It would always return 0 ! Instead we’d want to use 1 for this particular pairing.

All Together Now

0 + 1, 2, 3

So all together we might have something that looks a bit like this. Reducing the list of 1, 2, 3 into the starting value 0 using + to join values together.

More commonly that might look something like this:

0 + 1 + 2 + 3

But how exactly does it work? How do we trace that flow of data? Let’s take a look into that.

How Reduce Reduces

Each step of reduce, as explained in the below text

For every loop of reduce, we pass into the function our accumulator and our next value. Whatever is returned from that function becomes the new accumulator on the next run of reduce.

We start out with an initial value of 0 and add 1 to it, giving us a new accumulator of 1. That means next loop we start with 1 and add to it the next value in our list, 2 , giving us 3 . On our last loop we have an accumulator of 3 and a last value of 3 . Now that reduce has run out of numbers to, well, reduce, it returns the final accumulator it had. In this case, our answer is 6 .

What is Reduce?

Explaining the core elements of reduce, as mentioned in the text below

Reduce is a way to take a list of many things and reduce it into one thing using an initial value, and a way to join values together to make a new accumulator.

Masters of Functional Programming