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, a world that has only functions, living happily without any outside world dependencies, without states, and without mutations—forever. Functional programming is a buzzword these days. You might have heard about this term within your team or in a local group meeting. If you’re already aware of what that means, great. For those who don’t know the term, don’t worry. This chapter is designed 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? Later, 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 provides to developers.
What Is Functional Programming? Why Does It Matter?
Before we begin to explore what functional programming means, we have to answer another question: What is a function in mathematics? A function in mathematics can be written like this:
f (X) = Y
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 presented the definition of function in mathematics rather than in JavaScript. Did you? That’s a great question. The answer is pretty simple: Functional programming techniques are heavily based on mathematical functions and their ideas. Hold your breath, though; we are not going to teach you functional programming in mathematics, but rather use JavaScript. Throughout the book, however, we will be seeing the ideas of mathematical functions and how they are used to help understand functional programming.
Calculate Tax Function
The calculateTax function 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 this 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 on the outside world. In our calculateTax function, we have made the function depend on the global variable percentValue. Thus this function we have created can’t be called as a real function in a mathematical sense. Let’s fix that.
Rewritten calculateTax Function
Now our calculateTax function can be called as a real function. What have we gained, though? We have just eliminated 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 later in this chapter.)
Now we have shown the relationship between the math function and 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 their logic by depending only on their 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 a cachable and testable code base.
FUNCTIONS VS. METHODS IN JAVASCRIPT
We have talked about the word function a lot in this text. Before we move on, we want to make sure you understand the difference between functions and methods in JavaScript.
Simply put, a function is a piece of code that can be called by its name. It can be used to pass arguments that it can operate on and return values optionally.
A method is a piece of code that must be called by its name that is associated with an object.
A Simple Function
A Simple Method
There are two more important characteristics of functional programming that are missing in the definition. We discuss them in detail in the upcoming sections before we dive into the benefits of functional programming.
Referential Transparency
Referential Transparency Example
Now 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 given function with multiple threads without even the need to synchronize. Why? The reason for synchronizing comes from the fact that threads shouldn’t act on global data when running parallel. Functions that obey referential transparency are going to depend only on inputs from their argument; hence threads are free to run without any locking mechanism.
Because 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 know the factorial of 5 is 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 factorial is called for a second time with the input as 5, we can return the cached value instead of calculating it 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.
REFERENTIAL TRANSPARENCY IS A PHILOSOPHY
Referential transparency is a term that came from analytic philosophy ( https://en.wikipedia.org/wiki/Analytical_philosophy ). This branch of philosophy deals with natural language semantics and its meanings. Here the word referential or referent means the thing to which the expression refers. A context in a sentence is referentially transparent if replacing a term in that context with another term that refers to the same entity doesn’t alter the meaning.
That’s exactly how we have been defining referential transparency here. We have replaced the value of the function without affecting the context.
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 an imperative paradigm. We’ll take a problem and see how to solve it in an imperative and declarative fashion.
Iterating over the Array Imperative Approach
It works fine. In this approach to solve our problem, though, 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? It looks like we are telling the compiler what to do, however. In this case, we are telling the compiler, “Get array length, loop our array, get each element of the array using the index, and so on.” We call it an imperative solution. Imperative programming is all about telling the compiler how to do things.
Iterating over the Array Declarative Approach
Listing 1-7 does print exactly the same output as Listing 1-5. Here, though, we have removed the “how” parts like “Get array length, loop our array, get each element of an array using an index, and so on.” We have used an abstracted function, which takes care of the “how” part, leaving us, the developers, to worry about our problem at hand (the “what” part). We will be creating these built-in functions throughout the book.
Functional programming is about creating functions in an abstracted way that can be reused by other parts of the code. Now we have a solid understanding of what functional programming is; with this in mind, we can 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 JavaScript. We now have to answer a simple question: What are the benefits of functional programming? This section helps you see the huge benefits that functional programming offers us. Most of the benefits of functional programming come from writing pure functions. So before we see the benefits of functional programming, we need to know what a pure function is.
Pure Functions
A Simple Pure Function
This function double is a pure function because given an input, it is always going to return the same output. You can try it yourself. Calling the double function with input 5 always gives 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? They provide many benefits, which we discuss next.
Pure Functions Lead to Testable Code
The function calculateTax is not a pure function, mainly because for calculating its logic it depends on the external environment. The function works, but it is very difficult to test. Let’s see the reason for this.
badFunction Example
When the badFunction function is called it changes the global variable global to the value changed. Is it something to worry about? Yes. Imagine another function that depends on the 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 the case of debugging.
So we have seen with a simple example how a pure function can help us in easily testing the code. Now we’ll look at other benefits we get out of pure functions: reasonable code.
Reasonable Code
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 reading others’ code. Having a function with side effects in your code base makes it hard for other developers in your team to read. Code bases with pure functions are easy to read, understand, and test. Remember that a function (regardless of whether it is a pure function) must always have a meaningful name. For example, you can’t name the function double as dd given what it does.
SMALL MIND GAME
We are just replacing the function with a value, as if we know the result without seeing its implementation. That’s a great improvement in your thinking process about functions. We are substituting the function value as if that’s the result it will return.
To give your mind a quick exercise, see this reasoning ability with our in-built Math.max function.
What will be the result?
Did you see the implementation of max to give the result? No, right? Why? The answer to that question is Math.max is a pure function. Now have a cup of coffee; you have done a great job!
Parallel Code
Pure functions allow us to run the code in parallel. As a pure function is not going to change any of its environments, this means we do not need to worry about 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 a node environment that runs the function in parallel?
Impure Functions
Pure Functions
Here we have moved the global variable as arguments for both the functions, making them pure. Now we can run both functions in parallel without any issues. Because 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 functions help our code to run in parallel without any problems.
Cachable
Caching Achieved via Pure Functions
The code in Listing 1-12 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
This command does solve our problem via composing many functions. Composing is not only unique to UNIX/LINUX command lines; it is the heart of the functional programming paradigm. We call this 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. You want to count the number of lines in text. How will you solve it? Ahaa! You got the answer. 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 .
That’s a lot of benefits we are getting by following a simple definition. Before we close this chapter, we want to show the relationship between a pure function and a mathematical function. We tackle that next.
A Pure Function Is a Mathematical Function
Now imagine that longRunningFunction input ranges only from 1 to 11 integers, for example. Because 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 takes an input and maps over the output for the given range (in this case it’s 1–11). The important point to note here is that the inputs (in this case, the keys) have, mandatorily, a corresponding output (in this case, the result) in the object. In addition, there is no input in the key section that maps to two outputs.
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.
This 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? With this very simple example you can easily see how the mathematical function idea is borrowed in the functional paradigm world (as 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 ES8-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 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?
This code will execute without any error in the JavaScript world. The reason is that JavaScript is not a pure functional language (like Haskell) but rather a multiparadigm 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. This is the reason for this book’s title.
JavaScript is a language that has support for functions as arguments, passing functions to other functions, and so on, mainly because JavaScript treats functions as its first-class citizens (we 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 reviewed small, solid examples of functions and the functional programming paradigm in JavaScript. We also defined what pure functions are 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 ES8 context. Now with ES8 we have several ways to create functions; that’s exactly what we will be reading about in the next chapter.


























