### Explore functional programming and how using it can make your programs easier to read and debug.
![An introduction to functional programming in JavaScript](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/bus-rocket.png?itok=vHKRzkyW "An introduction to functional programming in JavaScript")
When Brendan Eich created JavaScript in 1995, he intended to do[Scheme in the browser][81]. Scheme, being a dialect of Lisp, is a functional programming language. Things changed when Eich was told that the new language should be the scripting language companion to Java. Eich eventually settled on a language that has a C-style syntax (as does Java), yet has first-class functions. Java technically did not have first-class functions until version 8, however you could simulate first-class functions using anonymous classes. Those first-class functions are what makes functional programming possible in JavaScript.
JavaScript is a multi-paradigm language that allows you to freely mix and match object-oriented, procedural, and functional paradigms. Recently there has been a growing trend toward functional programming. In frameworks such as[Angular][82]and[React][83], you'll actually get a performance boost by using immutable data structures. Immutability is a core tenet of functional programming. It, along with pure functions, makes it easier to reason about and debug your programs. Replacing procedural loops with functions can increase the readability of your program and make it more elegant. Overall, there are many advantages to functional programming.
### What functional programming isn't
Before we talk about what functional programming is, let's talk about what it is not. In fact, let's talk about all the language constructs you should throw out (goodbye, old friends):
Programming and development
* [New Python content][1]
* [Our latest JavaScript articles][2]
* [Recent Perl posts][3]
* [Red Hat Developers Blog][4]
* Loops
***while**
***do...while**
***for**
***for...of**
***for...in**
* Variable declarations with**var**or**let**
* Void functions
* Object mutation (for example:**o.x = 5;**)
* Array mutator methods
***copyWithin**
***fill**
***pop**
***push**
***reverse**
***shift**
***sort**
***splice**
***unshift**
* Map mutator methods
***clear**
***delete**
***set**
* Set mutator methods
***add**
***clear**
***delete**
How can you possibly program without those features? That's exactly what we are going to explore in the next few sections.
### Pure functions
Just because your program contains functions does not necessarily mean that you are doing functional programming. Functional programming distinguishes between pure and impure functions. It encourages you to write pure functions. A pure function must satisfy both of the following properties:
***Referential transparency:**The function always gives the same return value for the same arguments. This means that the function cannot depend on any mutable state.
***Side-effect free:**The function cannot cause any side effects. Side effects may include I/O (e.g., writing to the console or a log file), modifying a mutable object, reassigning a variable, etc.
Let's illustrate with a few examples. First, the**multiply**function is an example of a pure function. It always returns the same output for the same input, and it causes no side effects.
```
function multiply(a, b) {
return a * b;
}
```
[view raw][5][pure-function-example.js][6]hosted with ❤ by[GitHub][7]
The following are examples of impure functions. The**canRide**function depends on the captured**heightRequirement**variable. Captured variables do not necessarily make a function impure, but mutable (or re-assignable) ones do. In this case it was declared using**let**, which means that it can be reassigned. The**multiply**function is impure because it causes a side-effect by logging to the console.
```
let heightRequirement = 46;
// Impure because it relies on a mutable (reassignable) variable.
function canRide(height) {
return height >= heightRequirement;
}
// Impure because it causes a side-effect by logging to the console.
function multiply(a, b) {
console.log('Arguments: ', a, b);
return a * b;
}
```
[view raw][8][impure-functions.js][9]hosted with ❤ by[GitHub][10]
The following list contains several built-in functions in JavaScript that are impure. Can you state which of the two properties each one does not satisfy?
***console.log**
***element.addEventListener**
***Math.random**
***Date.now**
***$.ajax**(where**$**==the Ajax library of your choice)
Living in a perfect world in which all our functions are pure would be nice, but as you can tell from the list above, any meaningful program will contain impure functions. Most of the time we will need to make an Ajax call, check the current date, or get a random number. A good rule of thumb is to follow the 80/20 rule: 80% of your functions should be pure, and the remaining 20%, of necessity, will be impure.
There are several benefits to pure functions:
* They're easier to reason about and debug because they don't depend on mutable state.
* The return value can be cached or "memoized" to avoid recomputing it in the future.
* They're easier to test because there are no dependencies (such as logging, Ajax, database, etc.) that need to be mocked.
If a function you're writing or using is void (i.e., it has no return value), that's a clue that it's impure. If the function has no return value, then either it's a no-op or it's causing some side effect. Along the same lines, if you call a function but do not use its return value, again, you're probably relying on it to do some side effect, and it is an impure function.
### Immutability
Let's return to the concept of captured variables. Above, we looked at the**canRide**function. We decided that it is an impure function, because the**heightRequirement**could be reassigned. Here is a contrived example of how it can be reassigned with unpredictable results:
```
let heightRequirement = 46;
function canRide(height) {
return height >= heightRequirement;
}
// Every half second, set heightRequirement to a random number between 0 and 200.
[view raw][11][mutable-state.js][12]hosted with ❤ by[GitHub][13]
Let me reemphasize that captured variables do not necessarily make a function impure. We can rewrite the**canRide**function so that it is pure by simply changing how we declare the**heightRequirement**variable.
```
const heightRequirement = 46;
function canRide(height) {
return height >= heightRequirement;
}
```
[view raw][14][immutable-state.js][15]hosted with ❤ by[GitHub][16]
Declaring the variable with**const**means that there is no chance that it will be reassigned. If an attempt is made to reassign it, the runtime engine will throw an error; however, what if instead of a simple number we had an object that stored all our "constants"?
```
const constants = {
heightRequirement: 46,
// ... other constants go here
};
function canRide(height) {
return height >= constants.heightRequirement;
}
```
[view raw][17][captured-mutable-object.js][18]hosted with ❤ by[GitHub][19]
We used**const**so the variable cannot be reassigned, but there's still a problem. The object can be mutated. As the following code illustrates, to gain true immutability, you need to prevent the variable from being reassigned, and you also need immutable data structures. The JavaScript language provides us with the**Object.freeze**method to prevent an object from being mutated.
```
'use strict';
// CASE 1: The object is mutable and the variable can be reassigned.
let o1 = { foo: 'bar' };
// Mutate the object
o1.foo = 'something different';
// Reassign the variable
o1 = { message: "I'm a completely new object" };
// CASE 2: The object is still mutable but the variable cannot be reassigned.
const o2 = { foo: 'baz' };
// Can still mutate the object
o2.foo = 'Something different, yet again';
// Cannot reassign the variable
// o2 = { message: 'I will cause an error if you uncomment me' }; // Error!
// CASE 3: The object is immutable but the variable can be reassigned.
let o3 = Object.freeze({ foo: "Can't mutate me" });
// Cannot mutate the object
// o3.foo = 'Come on, uncomment me. I dare ya!'; // Error!
// Can still reassign the variable
o3 = { message: "I'm some other object, and I'm even mutable -- so take that!" };
// CASE 4: The object is immutable and the variable cannot be reassigned. This is what we want!!!!!!!!
[view raw][20][immutability-vs-reassignment.js][21]hosted with ❤ by[GitHub][22]
Immutability pertains to all data structures, which includes arrays, maps, and sets. That means that we cannot call mutator methods such as**array.prototype.push**because that modifies the existing array. Instead of pushing an item onto the existing array, we can create a new array with all the same items as the original array, plus the one additional item. In fact, every mutator method can be replaced by a function that returns a new array with the desired changes.
```
'use strict';
const a = Object.freeze([4, 5, 6]);
// Instead of: a.push(7, 8, 9);
const b = a.concat(7, 8, 9);
// Instead of: a.pop();
const c = a.slice(0, -1);
// Instead of: a.unshift(1, 2, 3);
const d = [1, 2, 3].concat(a);
// Instead of: a.shift();
const e = a.slice(1);
// Instead of: a.sort(myCompareFunction);
const f = R.sort(myCompareFunction, a); // R = Ramda
// Instead of: a.reverse();
const g = R.reverse(a); // R = Ramda
// Exercise for the reader:
// copyWithin
// fill
// splice
```
[view raw][23][array-mutator-method-replacement.js][24]hosted with ❤ by[GitHub][25]
The same thing goes when using a[**Map**][84]or a[**Set**][85]. We can avoid mutator methods by returning a new**Map**or**Set**with the desired changes.
```
const map = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three']
]);
// Instead of: map.set(4, 'four');
const map2 = new Map([...map, [4, 'four']]);
// Instead of: map.delete(1);
const map3 = new Map([...map].filter(([key]) => key !== 1));
// Instead of: map.clear();
const map4 = new Map();
```
[view raw][26][map-mutator-method-replacement.js][27]hosted with ❤ by[GitHub][28]
```
const set = new Set(['A', 'B', 'C']);
// Instead of: set.add('D');
const set2 = new Set([...set, 'D']);
// Instead of: set.delete('B');
const set3 = new Set([...set].filter(key => key !== 'B'));
// Instead of: set.clear();
const set4 = new Set();
```
[view raw][29][set-mutator-method-replacement.js][30]hosted with ❤ by[GitHub][31]
I would like to add that if you are using TypeScript (I am a huge fan of TypeScript), then you can use the**Readonly<T>**,**ReadonlyArray<T>**,**ReadonlyMap<K, V>**, and**ReadonlySet<T>**interfaces to get a compile-time error if you attempt to mutate any of those objects. If you call**Object.freeze**on an object literal or an array, then the compiler will automatically infer that it is read-only. Because of how Maps and Sets are represented internally, calling**Object.freeze**on those data structures does not work the same. But it's easy enough to tell the compiler that you would like them to be read-only.
Okay, so we can create new objects instead of mutating existing ones, but won't that adversely affect performance? Yes, it can. Be sure to do performance testing in your own app. If you need a performance boost, then consider using[Immutable.js][86]. Immutable.js implements[Lists][87],[Stacks][88],[Maps][89],[Sets][90], and other data structures using[persistent data structures][91]. This is the same technique used internally by functional programming languages such as Clojure and Scala.
[view raw][33][immutable-js-demo.js][34]hosted with ❤ by[GitHub][35]
### Function composition
Remember back in high school when you learned something that looked like**(f∘g)(x)**? Remember thinking, "When am I ever going to use this?" Well, now you are. Ready?**f∘g**is read "**f composed with g**." There are two equivalent ways of thinking of it, as illustrated by this identity:**(f∘g)(x) = f(g(x))**. You can either think of**f∘g**as a single function or as the result of calling function**g**and then taking its output and passing that to**f**. Notice that the functions get applied from right to left—that is, we execute**g**,followed by**f**.
A couple of important points about function composition:
1. We can compose any number of functions (we're not limited to two).
2. One way to compose functions is simply to take the output from one function and pass it to the next (i.e.,**f(g(x))**).
```
// h(x) = x + 1
// number -> number
function h(x) {
return x + 1;
}
// g(x) = x^2
// number -> number
function g(x) {
return x * x;
}
// f(x) = convert x to string
// number -> string
function f(x) {
return x.toString();
}
// y = (f ∘ g∘h)(1)
const y = f(g(h(1)));
console.log(y); // '4'
```
[view raw][36][function-composition-basic.js][37]hosted with ❤ by[GitHub][38]
There are libraries such as[Ramda][92]and[lodash][93]that provide a more elegant way of composing functions. Instead of simply passing the return value from one function to the next, we can treat function composition in the more mathematical sense. We can create a single composite function made up from the others (i.e.,**(f∘g)(x)**).
```
// h(x) = x + 1
// number -> number
function h(x) {
return x + 1;
}
// g(x) = x^2
// number -> number
function g(x) {
return x * x;
}
// f(x) = convert x to string
// number -> string
function f(x) {
return x.toString();
}
// R = Ramda
// composite = (f ∘ g∘h)
const composite = R.compose(f, g, h);
// Execute single function to get the result.
const y = composite(1);
console.log(y); // '4'
```
[view raw][39][function-composition-elegant.js][40]hosted with ❤ by[GitHub][41]
Okay, so we can do function composition in JavaScript. What's the big deal? Well, if you're really onboard with functional programming, then ideally your entire program will be nothing but function composition. There will be no loops (**for**,**for...of**,**for...in**,**while**,**do**) in your code. None (period). But that's impossible, you say! Not so. That leads us to the next two topics: recursion and higher-order functions.
### Recursion
Let's say that you would like to implement a function that computes the factorial of a number. Let's recall the definition of factorial from mathematics:
**n! = n * (n-1) * (n-2) * ... * 1**.
That is,**n!**is the product of all the integers from**n**down to**1**. We can write a loop that computes that for us easily enough.
```
function iterativeFactorial(n) {
let product = 1;
for (let i = 1; i <= n; i++) {
product *= i;
}
return product;
}
```
[view raw][42][iterative-factorial.js][43]hosted with ❤ by[GitHub][44]
Notice that both**product**and**i**are repeatedly being reassigned inside the loop. This is a standard procedural approach to solving the problem. How would we solve it using a functional approach? We would need to eliminate the loop and make sure we have no variables being reassigned. Recursion is one of the most powerful tools in the functional programmer's toolbelt. Recursion asks us to break down the overall problem into sub-problems that resemble the overall problem.
Computing the factorial is a perfect example. To compute**n!**, we simply need to take**n**and multiply it by all the smaller integers. That's the same thing as saying:
**n! = n * (n-1)!**
A-ha! We found a sub-problem to solve**(n-1)!**and it resembles the overall problem**n!**. There's one more thing to take care of: the base case. The base case tells us when to stop the recursion. If we didn't have a base case, then recursion would go on forever. In practice, you'll get a stack overflow error if there are too many recursive calls.
What is the base case for the factorial function? At first you might think that it's when**n == 1**, but due to some[complex math stuff][94], it's when**n == 0**.**0!**is defined to be**1**. With this information in mind, let's write a recursive factorial function.
```
function recursiveFactorial(n) {
// Base case -- stop the recursion
if (n === 0) {
return 1; // 0! is defined to be 1.
}
return n * recursiveFactorial(n - 1);
}
```
[view raw][45][recursive-factorial.js][46]hosted with ❤ by[GitHub][47]
Okay, so let's compute**recursiveFactorial(20000)**, because... well, why not! When we do, we get this:
So what's going on here? We got a stack overflow error! It's not because of infinite recursion. We know that we handled the base case (i.e.,**n === 0**). It's because the browser has a finite stack and we have exceeded it. Each call to**recursiveFactorial**causes a new frame to be put on the stack. We can visualize the stack as a set of boxes stacked on top of each other. Each time**recursiveFactorial**gets called, a new box is added to the top. The following diagram shows a stylized version of what the stack might look like when computing**recursiveFactorial(3)**. Note that in a real stack, the frame on top would store the memory address of where it should return after executing, but I have chosen to depict the return value using the variable**r**. I did this because JavaScript developers don't normally need to think about memory addresses.
### [stack-frames.png][49]
![The stack for recursively calculating 3! (three factorial)](https://opensource.com/sites/default/files/u128651/stack-frames.png "The stack for recursively calculating 3! (three factorial)")
The stack for recursively calculating 3! (three factorial)
You can imagine that the stack for**n = 20000**would be much higher. Is there anything we can do about that? It turns out that, yes, there is something we can do about it. As part of the**ES2015**(aka**ES6**) specification, an optimization was added to address this issue. It's called the_proper tail calls optimization_(PTC). It allows the browser to elide, or omit, stack frames if the last thing that the recursive function does is call itself and return the result. Actually, the optimization works for mutually recursive functions as well, but for simplicity we're just going to focus on a single recursive function.
You'll notice in the stack above that after the recursive function call, there is still an additional computation to be made (i.e.,**n * r**). That means that the browser cannot optimize it using PTC; however, we can rewrite the function in such a way so that the last step is the recursive call. One trick to doing that is to pass the intermediate result (in this case the**product**) into the function as an argument.
```
'use strict';
// Optimized for tail call optimization.
function factorial(n, product = 1) {
if (n === 0) {
return product;
}
return factorial(n - 1, product * n)
}
```
[view raw][50][factorial-tail-recursion.js][51]hosted with ❤ by[GitHub][52]
Let's visualize the optimized stack now when computing**factorial(3)**. As the following diagram shows, in this case the stack never grows beyond two frames. The reason is that we are passing all necessary information (i.e., the**product**) into the recursive function. So, after the**product**has been updated, the browser can throw out that stack frame. You'll notice in this diagram that each time the top frame falls down and becomes the bottom frame, the previous bottom frame gets thrown out. It's no longer needed.
### [optimized-stack-frames.png][53]
![The optimized stack for recursively calculating 3! (three factorial) using PTC](https://opensource.com/sites/default/files/u128651/optimized-stack-frames.png "The optimized stack for recursively calculating 3! (three factorial) using PTC")
The optimized stack for recursively calculating 3! (three factorial) using PTC
Now run that in a browser of your choice, and assuming that you ran it in Safari, then you will get the answer, which is**Infinity**(it's a number higher than the maximum representable number in JavaScript). But we didn't get a stack overflow error, so that's good! Now what about all the other browsers? It turns out that Safari is the only browser that has implemented PTC, and it might be the only browser to ever implement it. See the following compatibility table:
Other browsers have put forth a competing standard called[syntactic tail calls][95](STC). "Syntactic" means that you will have to specify via new syntax that you would like the function to participate in the tail-call optimization. Even though there is not widespread browser support yet, it's still a good idea to write your recursive functions so that they are ready for tail-call optimization whenever (and however) it comes.
### Higher-order functions
We already know that JavaScript has first-class functions that can be passed around just like any other value. So, it should come as no surprise that we can pass a function to another function. We can also return a function from a function. Voilà! We have higher-order functions. You're probably already familiar with several higher order functions that exist on the**Array.prototype**. For example,**filter**,**map**, and**reduce**, among others. One way to think of a higher-order function is: It's a function that accepts (what's typically called) a callback function. Let's see an example of using built-in higher-order functions:
.reduce((sum, price, i, array) => sum + price / array.length, 0);
console.log(averageSUVPrice); // 33399
```
[view raw][55][built-in-higher-order-functions.js][56]hosted with ❤ by[GitHub][57]
Notice that we are calling methods on an array object, which is characteristic of object-oriented programming. If we wanted to make this a bit more representative of functional programming, we could use functions provided by Ramda or lodash/fp instead. We can also use function composition, which we explored in a previous section. Note that we would need to reverse the order of the functions if we use**R.compose**, since it applies the functions right to left (i.e., bottom to top); however, if we want to apply them left to right (i.e., top to bottom), as in the example above, then we can use**R.pipe**. Both examples are given below using Ramda. Note that Ramda has a**mean**function that can be used instead of**reduce**.
// Using `pipe` executes the functions from top-to-bottom.
const averageSUVPrice1 = R.pipe(
R.filter(v => v.type === 'suv'),
R.map(v => v.price),
R.mean
)(vehicles);
console.log(averageSUVPrice1); // 33399
// Using `compose` executes the functions from bottom-to-top.
const averageSUVPrice2 = R.compose(
R.mean,
R.map(v => v.price),
R.filter(v => v.type === 'suv')
)(vehicles);
console.log(averageSUVPrice2); // 33399
```
[view raw][58][composing-higher-order-functions.js][59]hosted with ❤ by[GitHub][60]
The advantage of the functional programming approach is that it clearly separates the data (i.e.,**vehicles**) from the logic (i.e., the functions**filter**,**map**, and**reduce**). Contrast that with the object-oriented code that blends data and functions in the form of objects with methods.
### Currying
Informally,**currying**is the process of taking a function that accepts**n**arguments and turning it into**n**functions that each accepts a single argument. The**arity**of a function is the number of arguments that it accepts. A function that accepts a single argument is**unary**, two arguments**binary**, three arguments**ternary**, and**n**arguments is**n-ary**. Therefore, we can define currying as the process of taking an**n-ary**function and turning it into**n**unary functions. Let's start with a simple example, a function that takes the dot product of two vectors. Recall from linear algebra that the dot product of two vectors**[a, b, c]**and**[x, y, z]**is equal to**ax + by + cz**.
```
function dot(vector1, vector2) {
return vector1.reduce((sum, element, index) => sum += element * vector2[index], 0);
[view raw][61][dot-product.js][62]hosted with ❤ by[GitHub][63]
The**dot**function is binary since it accepts two arguments; however, we can manually convert it into two unary functions, as the following code example shows. Notice how**curriedDot**is aunary function that accepts a vector and returns another unary function that then accepts the second vector.
```
function curriedDot(vector1) {
return function(vector2) {
return vector1.reduce((sum, element, index) => sum += element * vector2[index], 0);
}
}
// Taking the dot product of any vector with [1, 1, 1]
// is equivalent to summing up the elements of the other vector.
const sumElements = curriedDot([1, 1, 1]);
console.log(sumElements([1, 3, -5])); // -1
console.log(sumElements([4, -2, -1])); // 1
```
[view raw][64][manual-currying.js][65]hosted with ❤ by[GitHub][66]
Fortunately for us, we don't have to manually convert each one of our functions to a curried form. Libraries including[Ramda][96]and[lodash][97]have functions that will do it for us. In fact, they do a hybrid type of currying, where you can either call the function one argument at a time, or you can continue to pass in all the arguments at once, just like the original.
```
function dot(vector1, vector2) {
return vector1.reduce((sum, element, index) => sum += element * vector2[index], 0);
}
const v1 = [1, 3, -5];
const v2 = [4, -2, -1];
// Use Ramda to do the currying for us!
const curriedDot = R.curry(dot);
const sumElements = curriedDot([1, 1, 1]);
console.log(sumElements(v1)); // -1
console.log(sumElements(v2)); // 1
// This works! You can still call the curried function with two arguments.
console.log(curriedDot(v1, v2)); // 3
```
[view raw][67][fancy-currying.js][68]hosted with ❤ by[GitHub][69]
Both Ramda and lodash also allow you to "skip over" an argument and specify it later. They do this using a placeholder. Because taking the dot product is commutative, it won't make a difference in which order we passed the vectors into the function. Let's use a different example to illustrate using a placeholder. Ramda uses a double underscore as its placeholder.
const giveMe2 = giveMe3(R.__, R.__, 'French Hens'); // Specify the third argument.
const giveMe1 = giveMe2('Partridge in a Pear Tree'); // This will go in the first slot.
const result = giveMe1('Turtle Doves'); // Finally fill in the second argument.
console.log(result);
// 1: Partridge in a Pear Tree
// 2: Turtle Doves
// 3: French Hens
```
[view raw][70][currying-placeholder.js][71]hosted with ❤ by[GitHub][72]
One final point before we complete the topic of currying, and that is partial application. Partial application and currying often go hand in hand, though they really are separate concepts. A curried function is still a curried function even if it hasn't been given any arguments. Partial application, on the other hand, is when a function has been given some, but not all, of its arguments. Currying is often used to do partial application, but it's not the only way.
The JavaScript language has a built-in mechanism for doing partial application without currying. This is done using the[**function.prototype.bind**][98]method. One idiosyncrasy of this method is that it requires you to pass in the value of**this**as the first argument. If you're not doing object-oriented programming, then you can effectively ignore**this**by passing in**null**.
```
function giveMe3(item1, item2, item3) {
return `
1: ${item1}
2: ${item2}
3: ${item3}
`;
}
const giveMe2 = giveMe3.bind(null, 'rock');
const giveMe1 = giveMe2.bind(null, 'paper');
const result = giveMe1('scissors');
console.log(result);
// 1: rock
// 2: paper
// 3: scissors
```
[view raw][73][partial-application-using-bind.js][74]hosted with ❤ by[GitHub][75]
### Wrapping up
I hope you enjoyed exploring functional programming in JavaScript with me! For some it may be a completely new programming paradigm, but I hope you will give it a chance. I think you'll find that your programs are easier to read and debug. Immutability will also allow you to take advantage of performance optimizations in Angular and React.
_This article is based on Matt's OpenWest talk,[JavaScript the Good-er Parts][77].[OpenWest][78]will be held July 12-15, 2017 in Salt Lake City, Utah._
Matt Banz - Matt graduated from the University of Utah with a degree in mathematics in May of 2008. One month later he landed a job as a web developer, and he's been loving it ever since! In 2013, he earned a Master of Computer Science degree from North Carolina State University. He has taught courses in web development for LDS Business College and the Davis School District Community Education program. He is currently a Senior Front-End Developer for Motorola Solutions.