Functional programming can be difficult to understand. Here’s a quick way to “get-it” using food emojis:

💩 = [🍔, 🍟, 🍪].reduce(eat)

Beautiful right? If you combine hamburgers, fries, and cookies in the eat reducer, you end up with poop!

If that went over your head, we can start simpler with some basic math:

😂 = 😢 + 😀 😶 = 🤐 - 😐

Let’s take another functional example. We have an array of clouds. We’re going to process that array, then return another array.

[🌩️, ⛈️] = [☁️, 🌧️].map(add(⚡))

Functional programming at it’s best! We took some cloud emojis, added lightning to each one, and made clouds with lightning! It’s like magic!

Before we ride into Crazy Town, let’s look at an example using some different paradigms:

addLighting = item => item + ⚡

🌩️ = addLightning(☁️) addSun = item => item + ☀️

⛅ = addSun(☁️)

While this code works, it’s not very DRY (Don’t Repeat Yourself). For each add operation we want to do, we have to create a whole new function by hand. Instead, we could try a better solution:

add = (item, additive) => item + additive 🌩️ = add(☁️, ⚡) ⛅ = add(☁️, ☀️)

Fantastic! We’ve created a generic function that takes multiple parameters and returns a value. But we still have an issue! What if we want to call add on every item in an array the same as we did before with map ? Doing this imperatively, it will look something like this:

clouds = [☁️, 🌧️]

stormyClouds = [] add = (item, additive) => item + additive for (let i = 0, l = clouds.length; i < l; i++) {

stormyClouds

.push(

add(clouds[i], ⚡)

)

}

It looks simple enough, but for loops are really messy. Not only are we mutating i on each round of the loop, but we’re also pushing values into the stormyClouds array outside of it.

JavaScript also has for-in loops which keep track of i for you; therefore, your for loop can be a lot cleaner.

for (let i in clouds) {

stormyClouds

.push(

add(clouds[i], ⚡)

)

}

But why pass i , the index, when all we really care about is the value at that index? A foreach loop, known as a for-of in JavaScript, gets us far closer to the functional approach:

for (let cloud of clouds) {

stormyClouds

.push(

add(cloud, ⚡)

)

}

Since we’re already here, we can quickly clean this up by replacing the for-of with a forEach :

clouds

.forEach(cloud => {

stormyClouds

.push(

add(cloud, ⚡)

)

})

Slightly better, but not satisfying. Since forEach takes a function, we can create that function somewhere else and then pass it in like so:

addLightning = cloud => {

stormyClouds

.push(

add(cloud, ⚡)

)

} clouds.forEach(addLightning)

While the addLighting function makes for easy unit testing, we’ve circled back on ourselves. Now we’re back to creating one-use functions. If you wanna write an addSun , you’re going to be copy-pasting a lot of the same code. Our code still isn’t DRY, but we wrote it generically. What’s going on?

This is where we need a closure. The original add function we used with map actually looks like this:

add = additive => item => item + additive

This add function allows us to generate functions. It takes an additive and then returns another function that takes an item . The key is that calling add the first time doesn’t actually do anything; it just stores additive so when the inner function is called, it has access to additive even though it’s never passed in!

Now we can generate addLighting and addSun on-the-fly:

addLightning = add(⚡)

🌩️ = addLightning(☁️) addSun = add(☀️)

⛅ = addSun(☁️)

Here’s another way to look at it:

🌩️ = add(⚡)(☁️) ⛅ = add(☀️)(☁️)

Pretty weird right? Why would we return a function then call that function when we can just take two parameters and be done with it? It’s because of the copy-paste problem. With closures, we can remove a lot of boilerplate and create generic functions that return other generic functions.

Using the procedural method, this is what we’d normally write:

clouds = [☁️, 🌧️]

stormyClouds = []

sunnyClouds = [] add = (item, additive)=> item + additive addLightning = cloud => {

stormyClouds

.push(

add(cloud, ⚡)

)

} addSun = cloud => {

sunnyClouds

.push(

add(cloud, ☀️)

)

} for(let i = 0, l = clouds.length; i < l; i++) {

addLightning(clouds[i])

} for(let i = 0, l = clouds.length; i < l; i++) {

addSun(clouds[i])

} [🌩️, ⛈️] = stormyClouds

[⛅, 🌦️] = sunnyClouds

But with functional programming, we can write very clean code that does the exact same thing:

add = additive => item => item + additive [🌩️, ⛈️] = [☁️, 🌧️].map(add(⚡))

[⛅, 🌦️] = [☁️, 🌧️].map(add(☀️))

Super mega powerful! Only 3 lines of code for the same functionality! To delve a bit further, we can write a subtract function:

subtract = subtractor => item => item - subtractor

And now we can do the same operation backward:

[☁️, 🌧️] = [🌩️, ⛈️️].map(subtract(⚡))

[☁️, 🌧️] = [⛅, 🌦️].map(subtract(☀️))

Nifty! Let’s take this a step further. We can actually map the array and then map it again by chaining these functions:

[⛅, 🌦️] = (

[🌩️, ⛈️️]

.map(subtract(⚡))

.map(add(☀️))

)

What was once stormy is now sunny. Subtract out the lightning and add in the sun. Each time map is called, it returns a new array. The first time you run it, we’re left with regular lightning-less clouds. The second time you run it, it adds sun. Super simple, mega powerful.

FEEL THE POWER!