The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that.
—ROBERT C. MARTIN
Welcome to the functional programming world. The world, which has only functions, living happily without any outside world dependencies, without states, without mutations – forever. Functional programming is a buzz in recent days. You might have heard about this term within your team, in your local group meeting, and have thought about this. If you’re already aware of what that means, this is great! But for those who don’t know the term, don’t worry. This chapter is for that purpose: to introduce you to Functional terms in simple English.
We are going to begin this chapter by asking a simple question: what is a function in Mathematics? Then later on we are going to create a function in JavaScript with a simple example using our function definition. The chapter ends by explaining the benefits that functional programming gives to our developers.
What Is Functional Programming? Why It Matters?
Before we begin to see what the functional programming term means , we have to answer another question: what is a function in mathematics? A function in mathematics can be written like this:
f(X) = YThe statement can be read like “A Function F, which takes X as its argument, and returns the output Y.” X and Y can be any number, for instance. That’s a very simple definition. But there are key takeaways in the definitions :
A function must always take an argument.
A function must always return a value.
A function should act only on its receiving arguments (i.e., X) not the outside world.
For a given X, there will be only one Y.
You might be wondering why we saw the definition of functions in mathematics rather than in JavaScript. Did you? That sounds like a great question to me. The answer is pretty simple: functional programming techniques are heavily based on mathematical functions and its ideas. But hold your breath – we are not going to teach you functional programming in mathematics, but rather use JavaScript to teach them. But throughout the book, we will be seeing the ideas of mathematical functions and how they are used in order to understand functional programming.
Now with that definition in place, we are going to see the examples of functions in JavaScript.
Imagine we have to write a function that does the tax calculation. How are you going to do this in JavaScript?
Note
All the examples in the book will be written with ES6. The code snippets in the book are stand-alone so that you can copy and paste them in any one of your favorite browsers that supports ES6. All the examples are run in the Chrome browser version 51.0.2704.84. The ES6 spec is over here: http://www.ecma-international.org/ecma-262/6.0/
We can implement such a function like this as shown in Listing 1-1:
Listing 1-1. Calculate Tax Function in ES6
var percentValue = 5;var calculateTax = (value) => { return value/100 * (100 + percentValue) }
The above function calculateTax does exactly what we want to do. You can call this function with the value, which will return the calculated tax value in the console. It looks neat, doesn’t it? Let’s pause for a moment and analyze the above function with respect to our mathematical definition. One of the key points of our mathematical function term is that the function logic shouldn’t depend upon the outside world. In our above-defined function calculateTax, we have made the function depend on the global variable percentValue. Thus the above function we have created can’t be called as a real function in a mathematical sense. So let’s fix that. (Doubt – Can’t change font in the template why?)
The fix is very straightforward: we have to just move the percentValue as our function argument:
Listing 1-2. Calculate Tax Function Rewritten
var calculateTax = (value, percentValue) => { return value/100 * (100 + percentValue) }Now our function calculateTax can be called as a real function. But what have we gained? We have just made the elimination of global variable access inside our calculateTax function. Removing global variable access inside a function makes it easy for testing. (We will talk about the functional programming benefits in this chapter later on)
Now we have made our relationship with the Math function to our JavaScript function. With this simple exercise, we can define functional programming in simple technical terms. Functional programming is a paradigm in which we will be creating functions that are going to work out its logic by depending only on its input. This ensures that a function, when called multiple times, is going to return the same result. The function also won’t change any data in the outside world, leading to cachable and testable codebase.
There are two more important characteristics of Functional programing that are missing in the definition. We are going to discuss them in detail in the upcoming sections before we dive into the benefits of functional programming.
Referential Transparency
With our above definition of function, we have made a statement that all the functions are going to return the same value for the same input. And this property of a function is called a Referential transparency. We will take a simple example as shown in Listing 1-5:
Listing 1-5. Referential Transparency Example
var identity = (i) => { return i }In the above code snippet we have defined a simple function called identity. This function is going to return whatever you‘re passing as its input; that is, if you’re passing 5, it’s going to return back the value 5 (i.e., the function is just acts as a mirror or identity). Note that our function does operate only on the incoming argument ‘i’, and there is no global reference inside our function (remember in Listing 1-2, we removed ‘percentValue’ from global access and made it an incoming argument). This function satisfies the conditions ofReferential Transparency. Now imagine this function is used between other function calls like this:
sum(4,5) + identity(1)With our Referential Transparency definition we can convert the above statement into this:
sum(4,5) + 1Now this process is called a Substitution model as you can directly substitute the result of the function as is (mainly because the function doesn’t depend on other global variables for its logic) with its value. This leads to parallel code and caching. Imagine that with this model, you can easily run the above function with multiple threads without even the need of synchronizing! Why? The reason for synchronizing comes from the fact that threads shouldn’t act upon global data when running parallel. Functions that obey Referential Transparency are going to depend only on inputs from its argument; hence threads are free to run without any locking mechanism!
And since the function is going to return the same value for the given input, we can, in fact cache it! For example, imagine there is a function called ‘factorial’, which calculates the factorial of the given number. ‘Factorial’ takes the input as its argument for which the factorial needs to be calculated. We all know the ‘factorial’ of ‘5’ going to be ‘120’. What if the user calls the ‘factorial’ of ‘5’ a second time? If the ‘factorial’ function obeys Referential transparency, we know that the result is going to be ‘120’ as before (and it only depends on the input argument). With this characteristic in mind, we can cache the values of our ‘factorial’ function. Thus if a ‘factorial’ is called for the second time with the input as ‘5’, we can return the cached value instead of calculating once again
Here you can see how a simple idea helps in parallel code and cachable code. We will be writing a function in our library for caching the function results, later in the chapter.
Imperative, Declarative, Abstraction
Functional programming is also about being declarative and writing abstracted code. We need to understand these two terms before we proceed further. We all know and have worked on N imperative paradigm . We’ll take a problem and see how to solve it in an imperative and declarative fashion.
Suppose you have a list or array and want to iterate through the array and print it to the console. The code for might look like this:
Listing 1-6. Iterating over the Array Imperative Approach
var array = [1,2,3]for(i=0;i<array.length;i++)console.log(array[i]) //prints 1, 2, 3
It works fine. But in the above approach to solve our problem, we are telling exactly “how” we need to do it. For example, we have written an implicit for loop with an index calculation of the array length and printing the items. We will stop here. What was the task here? “Print the array elements,” right? But it looks like we are telling the compiler what to do. In this case, we are telling “Get Array Length, Loop our array, Get each Element of array using index etc.” We call it an “imperative” solution. Imperative programming is all about telling the compiler “how” to do the things.
We will now switch to the other side of the coin, Declarative programming. In Declarative programming , we are going to tell “what” the compiler needs to do rather than the “how” parts. The “how” parts are being abstracted into common functions (these functions are called as Higher-Order functions, which we will cover in the upcoming chapters). Now we can use the in-built forEach function to iterate the array and print it.
Listing 1-7. Iterating over the Array Declarative Approach
var array = [1,2,3]array.forEach((element) => console.log(element)) //prints 1, 2, 3
The above code snippet does print exactly the same output in the previous Listing 1-5. But here we have removed the “how” parts like “Get Array Length, Loop our array, Get each Element of array using index, etc.” We have used an abstracted function, which takes care of “how” part, leaving us the developers to worry about our problem in hand (“what” part). That’s great! We will be creating these in-built functions throughout the textbook!
Functional programming is about creating functions in an abstracted way, which can be reused by other parts of the code. Now we have a solid understanding of what a functional programming is; with this in mind, we can go and explore the benefits of functional programming.
Functional Programming Benefits
We have seen the definition of functional programming and a very simple example of a function in the JavaScript language. But we have to answer a simple question: “What are the benefits of Functional programming?” This section will help you see through the lenses and see the huge benefits that functional programming is opting to offer us! Most of the benefits of Functional programming come from writing Pure Functions. So before we see the benefits of Functional programming, we will see what a pure function is.
Pure Functions
With our definition in place, we can define what is meant by Pure functions. Pure functions are the functions that return the same output for the given input. Take an example as given in Listing 1-8:
Listing 1-8. A Simple Pure Function
var double = (value) => value * 2;The above function ‘double’ is a pure function just because given an input, it is going to always return the same output. You can try yourself. Calling the double function with input 5 always gives back the result as 10! Pure functions obey Referential transparency. Thus we can replace double(5) with 10, without any hesitations.
So what’s the big deal about Pure Functions? It has many benefits to give to us. We’ll discuss one after the other in the following text.
Pure Functions Lead to Testable Code
Functions that are not pure have side effects. Take our previous tax calculation example (Listing 1-1):
var percentValue = 5;var calculateTax = (value) => { return value/100 * (100 + percentValue) } //depends on external environment percentValue variable
The function calculateTax is not a pure function, mainly because for calculating its logic it depends on the external environment. However, the function works but the function is very tough to test! Let’s see the reason for this.
Imagine we are planning to run a test for our calculateTax function three times for three different tax calculations. We set up the environment like this:
calculateTax(5) === 5.25calculateTax(6) === 6.3calculateTax(7) === 7.3500000000000005
The entire test passes! But hold on, since our original calculateTax function depends on the external environment variable percentValue, things can go wrong. Imagine the external environment is changing the variable percentValue while you are running the same test cases:
calculateTax(5) === 5.25// percentValue is changed by other function to 2calculateTax(6) === 6.3 //will the test pass?// percentValue is changed by other function to 0calculateTax(7) === 7.3500000000000005 //will the test pass or throw exception?
As you can see here the function is very hard to test. However we can easily fix the issue, by removing the external environment dependency from our function, leading the code to this:
var calculateTax = (value, percentValue) => { return value/100 * (100 + percentValue) }Now you can test the above function without any pain! Before we close this section, we need to mention an important property about Pure function, which is “Pure Function also shouldn’t mutate any external environment variables.”
In other words, the pure function shouldn’t depend on any external variables (like shown in the example) and also change any external variables. We’ll not take a quick look what we meant by changing any external variables. For example, consider the following code in Listing 1-9:
Listing 1-9. BadFunction Example
var global = "globalValue"var badFunction = (value) => { global = "changed"; return value * 2 }
When ‘badfunction’ function is called it changes the global variable ‘global’ to value ‘changed’. Is it something to worry about? Yes! Imagine another function that depends on ‘global’ variable for its business logic! Thus, calling ‘badFunction’ affects other functions’ behavior. Functions of this nature (i.e., functions that have side effects) make the code base hard to test. Apart from testing, these side effects will make the system behavior very hard to predict in case of debugging!
So we have seen with simple example of how a pure function can help us in easy testing the code. Now we’ll look at other benefits we get out of Pure Functions – Reasonable Code.
Reasonable Code
As developers we should be good at reasoning about the code or a function. By creating and using Pure functions we can achieve that very simply. To make this point clearer, we are going to use a simple example of function double (from Listing 1-8):
var double = (value) => value * 2By looking at this function name we can easily reason that this function doubles the given number and nothing else! In fact, using our Referential transparency concept, we can easily go ahead and replace the double function call with the corresponding result! Developers spend most of their time in reading others’ code. Having a function with side effects in your code base is hard to read for other developers in your team. Code base with pure functions are easy to read, understand, and test. Remember that a function (regardless if it’s pure function) must always have a meaningful name. With that said, you can’t name function ‘double’ as ‘dd’ given what it does.
Parallel Code
Pure function allows us to run the code in parallel. As pure function is not going to change any of its environments, this means we do not need to worry about the synchronizing at all! Of course JavaScript doesn’t have real threads to run the functions in parallel, but what if your project uses WebWorkers for running multiple things in parallel? Or a server-side code in node environment that runs the function in parallel?
For example, imagine we have the following code as given in Listing 1-10:
Listing 1-10. Impure Functions
let global = "something"let function1 = (input) => {// works on input//changes globalglobal = "somethingElse"}let function2 = () => {if(global === "something"){//business logic}}
What if we need to run both ‘function1’ and ‘function2’ in parallel? Imagine thread one (T-1) picks ‘function1’ to run. Thread two (T-2) picks ‘function’ to run. Now both threads are ready to run and here comes the problem. What if T-1 runs before T-2? Since both functions (‘function1’ and ‘function2’) depend on global variable ‘global’, running these functions in parallel causes undesirable effects. Now change these functions into a pure function as explained in Listing 1-11:
Listing 1-11. Pure Functions
let function1 = (input,global) => {// works on input//changes globalglobal = "somethingElse"}let function2 = (global) => {if(global === "something"){//business logic}}
Here we have moved ‘global’ variable as arguments for both the functions making them pure. Now we can run both functions on parallel without any issues. Since the functions don’t depend on an external environment (‘global’ variable), we aren’t worried about thread execution order as with Listing 1-10.
This section shows us how pure function helps our code to run in parallel without any problems.
Cachable
Since the pure function is going to always return the same output for the given input, we can cache the function outputs. To make this more concrete, we can take a simple example. Imagine we have a function that does do time-consuming calculations. We will name this function longRunningFunction:
var longRunningFunction = (ip) => { //do long running tasks and return }If longRunningFunction function is a pure function, then we know that for the given input, it’s going to return us the same output! Now with that point in mind, why do we need to call the function again with its input multiple times? Can’t we just replace the function call with the function’s previous result? (Again note here how we are using the referential transparency concept, thus replacing the function with the previous result value and leaving the context unchanged). Imagine we have a bookkeeping object, which does keep all the function call results of longRunningFunction like this:
var longRunningFnBookKeeper = { 2 : 3, 4 : 5 . . . }The longRunningFnBookKeeper is a simple JavaScript object, which is going to hold all the input (as keys) and outputs (as values) in it as a result of invoking longRunningFunction functions. Now with our pure function definition in place, we can check if the key is present in longRunningFnBookKeeper before invoking our original function, like what is shown in Listing 1-12:
Listing 1-12. Caching Achieved via Pure Functions
var longRunningFnBookKeeper = { 2 : 3, 4 : 5 }//check if the key present in longRunningFnBookKeeper//if get back the result else update the bookkeeping objectlongRunningFnBookKeeper.hasOwnProperty(ip) ?longRunningFnBookKeeper[ip] :longRunningFnBookKeeper[ip] = longRunningFunction(ip)
The above code is relatively straightforward. Before calling our real function, we are checking if the result of that function with the corresponding ip is in the bookkeeping object. If yes, we are returning it, or else we are calling our original function and updating the result in our bookkeeping object as well. Did you see how easily we have made the function calls cachable by using less code? That’s the power of pure functions!
We will be writing a functional lib, which does the caching, or technical memorization, of our pure function calls later in the book!
Pipelines and Composable
With pure functions we are going to do only one thing in that function. We have seen already how the pure function is going to act as a self-understanding of what that function does by seeing its name. Pure functions should be designed such a way that it should do only one thing. Doing only one thing and doing it perfectly is a UNIX philosophy; we will be following the same while implementing our pure functions. There are many commands in UNIX and LINUX platforms, which we are using for day-to-day tasks. For example, we use cat to print the contents of the file, grep to search the files, wc to count the lines, etc. These commands do solve one problem at a time. But we can composeor pipeline to do the complex tasks. Imagine we want to find a specific name in a text file and count its occurrences. How we will be doing that in our command prompt? The command looks like this:
cat jsBook | grep –i “composing” | wcThe above command does solve our problem via composing many functions. Composing is not only unique to UNIX/LINUX command lines, but they are the heart of the Functional programming paradigm. We call them Functional Composition in our world. Imagine these same command lines have been implemented in JavaScript functions. We can use them with the same principles to solve our problem!
Now think about another problem in a different way to solve. You want to count the number of lines in text. How will you solve it? Ahaa! You got the answer. Isn’t?
The commands are in fact a pure function with respect to our definition. It takes an argument and returns the output to the caller without affecting any of the external environments!
Note
You might be thinking, does JavaScript support the operator “|” for composing functions? The answer is no; however we can create one. We will be creating the corresponding
That’s a lot of benefits we are getting by following a simple definition. Before I close this chapter, I want to show the relationship between Pure function and an Mathematical Function. We will tackle that next!
Pure Function Is a Mathematical Function
In the section “Cachable” we saw a code snippet (Listing 1-12):
var longRunningFunction = (ip) => { //do long running tasks and return }var longRunningFnBookKeeper = { 2 : 3, 4 : 5 }//check if the key present in longRunningFnBookKeeper//if get back the result else update the bookkeeping objectlongRunningFnBookKeeper.hasOwnProperty(ip) ?longRunningFnBookKeeper[ip] :longRunningFnBookKeeper[ip] = longRunningFunction(ip)
The main aim was to cache the function calls. We did so by the bookkeeping object. Imagine we have called the longRunningFunction many times so that our longRunningFnBookKeeper grows into the object, which looks like this:
longRunningFnBookKeeper = {1 : 32,2 : 4,3 : 5,5 : 6,8 : 9,9 : 10,10 : 23,11 : 44}
Now imagine that longRunningFunction input ranges only from 1-11 integers (just for an example). And since we have already built the bookkeeping object for this particular range, we can refer only the longRunningFnBookKeeper to say the output longRunningFunction for the given input.
Let’s analyze this bookkeeping object. This object gives us the clear picture that our function longRunningFunction does takes a input and maps over the output for the given range (in this case it’s 1-11). And the important point to note over here is that the inputs (in this case, the keys) have, mandatorily, a corresponding output (in this case, the result) in the object. And also there is no input in the key section that maps to two outputs!
With this analysis we can revisit the Mathematical Function definition (this time a more concrete definition from Wikipedia). ( https://en.wikipedia.org/wiki/Function_(mathematics ):
In mathematics, a function is a relation between a set of inputs and a set of permissible outputs with the property that each input is related to exactly one output. The input to a function is called the argument and the output is called the value. The set of all permitted inputs to a given function is called the domain of the function, while the set of permissible outputs is called the codomain.
The above definition is exactly the same as our Pure functions! Have a look at our longRunningFnBookKeeper object. Can you find the domain and codomain of our function? Yeah, you can! With this very simple example you can easily see how the Mathematical Function idea is borrowed into Functional paradigm world (as I stated in the beginning of the chapter).
What We Are Going to Build
We have talked a lot about functions and functional programming in this chapter. With this fundamental knowledge we are going to build the functional library called ES6-Functional . This library will be built chapter by chapter throughout the text. By building the functional library you will be exploring how JavaScript functions can be used (in a functional way) and also at the same time how functional programming can be applied in day-to-day activities (using our created function to solve the problem in our code base)!
Is JavaScript a Functional Programming Language?
Before we close this chapter, we have to take a step back and answer a fundamental question. Is JavaScript a functional programming language? The answer is yes and no. We said in the beginning of the chapter that functional programming is all about functions, which have to take at least an argument and return a value. But to be frank we can create a function in JavaScript that can take no argument and in fact return nothing. For example, the below code is a valid code in the JavaScript engine:
var useless = () => {}The above code will execute without any error in the JavaScript world! The reason is that being JavaScript is not a pure functional language (like Haskell) but rather a Multi-paradigm language. However the language is very much suitable for the functional programming paradigm as discussed in this chapter. The techniques and the benefits that we have discussed up to now can be applied in pure JavaScript! And that’s the reason for this book’s title!
JavaScript is a language that has a support for Function as arguments, passing functions to another functions, etc – mainly because JavaScript treats functions as its first-class citizens (we will talk more about this in upcoming chapters). Because of the constraints according to the definition of the term function, we as developers need to take them into account while creating them in the JavaScript world. By doing so, we will gain many advantages from the functional paradigm as discussed in this chapter.
Summary
In this chapter we have seen what Functions are in Math and in the programming world. We started with a simple definition of function in mathematics and went over seeing small and solid examples of functions and functional programming paradigm in JavaScript. We also defined what Pure function is and discussed, in detail, their benefits. At the end of the chapter we also showed the relationship between Pure functions and Mathematical functions. We also discussed how JavaScript could be treated as a functional programming language. A lot of progress has been made in this chapter.
In the next chapter, we will be reading about creating and executing functions in the ES6 context. Now with ES6 we have several ways to create functions; that’s exactly what we will be reading about in the next chapter!






