We declare what result we want from a program and we just let someone else deal with the implementation details. Someone out there wrote the map method on arrays and somehow it magically takes this function and gives us back a new array, right? This is declarative programming, and functional is a type of declarative programming. So you see here we have the same function. We give it an array and return the values one at a time, multiplied by 2. Functional would kind of look like this. We would have a couple functions. We would have a double function that takes a value and returns its double. We would have a map function which takes function and then returns a new function that takes an array. That's the key there. Returns a function. Returns an array and then we make our map over it. So that's the composition of passing double into map and then an array into that composed function. I know I just said a whole bunch of words. Let me teach you them. So let's start with higher order functions.
So that add function I was telling you about, right? We take an X and a Y and return an X and a Y. And you're like... Kyle, that's really boring. But how many times have you seen what seems to be a really simple function in your code and you have a mutation, like on the impure example? You're walking through a pull request and someone decides they have to mutate a state somewhere else and they're trying to do four things in the same function. Pure functions come down to something really simple and really easily tested. If you have this add function, you know immediately how to write a test for it. You would give it some data and expect the data out. It would always be the same. We need pure functions in order to do functional programming. And true functional programming languages like Haskell or some of the frontend languages coming out these days such as Elm and Reason, they will push you to do this all the time. You'll write everything in pure functions. Purity leads to easily testable functionality, as I suggested. But it also does this thing where it creates these trustworthy contacts between our functions.
And that's a fact that we can utilize throughout our application. And that leads us to what I call the meat and potatoes of functional programming and getting into it. It's currying and partial application. And I literally mean meat and potatoes to some degree. I love yellow curry. Anyone else a fan of curry here? So I'm talking about this guy. Haskell Brooks Curry. He's a super smart dude. And I'm not talking about the food, which is super delicious food. Right? Haskell Brooks Curry was this genius... His claim to fame is what's called combinatory logic and advancing mathematical logic in that way. I won't get into that. I don't have time for it. But his name is so important that it's become three different programming languages, including the most popular one you probably know -- Haskell. But this technique was named after him too. And currying is the technique of refactoring a function that normally accepts multiple arguments into one that accepts them one at a time. So the canonical curried function that everyone learns the first time is the add function. That's why I've been talking about it. So add normally takes an X and a Y, but if we make it a curried function, we're gonna use a higher order function -- I brought that word back -- and return a new function that waits for its second parameter. You get that? We get an X. Return a function that waits for the Y. When it gets the Y, it finally evaluates. It doesn't evaluate beforehand. And if you're already using ES6, you get to use arrow functions to write this, and it's really elegant. You become really good at writing argument, returns, argument, returns, argument, and writing out your curried functions. So why was that useful?
But do you remember doing some math and you had an equation like f of x=y? Anyone remember that? So in math, all functions are pure functions. Right? They always give you one output for the input that you give. That's kind of nice. Unlike our programs at work where, like, I call a function and 8 things happen and I don't know why it's doing that, and now I have to spend an hour and a half banging my head against a wall trying to solve a problem, right? Math gives us pure functions. Functional programming demands that we use pure functions. As we said before, though, we can give functions a function, as an argument. And that's what composition is. So if you look at the bottom of this slide, F of g of x=y is a composition of a G function and fed into an F function. So in programming, we rarely name functions a single letter. If you do, stop. Just don't do it. I feel bad for your teammates, if you write functions that only have a single letter. But nesting functions can be really, really ugly.
And so I have this example here. I've made three curried functions at the top. They only take one argument, so I didn't really have to curry much. But they all take a string and they return something. The first one is a scream, the second is an exclaim, the third is a repeat, and I supply it a string. So what I get is I can create this result by composing these functions together, where I first scream at Bob, and then I exclaim at Bob, and then I repeat it at Bob, and if there's anyone named Bob here, I'm really sorry. But we yell at Bob twice that the world is coming to an end. But that could be really ugly, especially if you have really long, clear function names. Right? If you're following clean code principles, you might be like... If this does X, blah-blah-blah blah-blah... And you have a 40-character function name. Imagine trying to compose those. That would be a nightmare to try and read.
So... There's a great other way to do it. Instead of nesting functions, what if we use that... Excuse me. What if we use that currying and partial application that we learned to create new functions for us that would do the composition for us? So I'm gonna introduce you to what's called the compose function. And if you get into this, you're gonna be using compose all the time. It's a little hard to read sometimes the first time, so I want to walk you through it. Compose is a function that takes any number of functions as arguments. Any number. It creates an array out of them. We're using the REST parameter, if you're familiar with ES6. And it returns a new function that's waiting a value. In this case, I call it X. And what it does -- it does a reduce, but a reduce right. So we're gonna start at the end of the array and work our way to the front. The reason we do that, rather than left to right, is it's more mathematical. We want to work from the inside of our function out, rather than some weird outside-in composition. We take the last function, supply it our starting value, and that gets passed as the accumulator. And we return the value that's derived from firing that function with that value. And then it's fed into the next one and fed into the next one and fed into the next one. You following me? And eventually we get our end result.