What is functional programming?
In simple terms, functional programming is a software development style that places a major emphasis on the use of functions.
What better text to print than the good ol “Hello World”:
document.querySelector('#msg').innerHTML = '<h1>Hello world</h1>'
This program is simple, but because everything is hardcoded, you can’t use it to display messages dynamically. Say you wanted to change the formatting, the content, or perhaps the target element; you’d need to rewrite the entire expression. Maybe you decide to wrap this code with a function and make the change points parameters, so you can write it once and use it with any configuration:
function printMessage(elementId, format, message) {
document.querySelector('#{elementId').innerHTML = `<${format}>${message}</$Pformat}>`
}
printMessage('msg', 'h1', 'Hello World')
An improvement, indeed, but still not a complete reusable piece of code. Suppose you want to write to a file instead of an HTML page. You need to take the simple thought process of creating parameterized functions to a different level, where parameters aren’t just scalar values but can also be functions themselves that provide additional functionality. Functional programming is a bit like using functions on steroids, because you sole objective is to evaluate and combine lots of functions with others to achieve greater behavior.
// Listing 1.1 Functional `printMessage`
var printMessage = run(addToDom('msg'), h1, echo)
printMessage('Hello World')
Without a doubt, this looks a radically different than the original. For starters, h1
isn’t a scalar anymore; it’s a function just like addToDom
and echo
. Visually, it feels as though you’re creating a function from smaller functions.
There’s a reason for this madness. Listing 1.1 captures the process of decomposing a program into smaller pieces that are more usable, more reliable, and easier to understand, and then combining them to form an entire program that is easier to reason about as a whole. Every functional program follows this fundamental principle.
For the time being, you’ll use a magical function, run
, to invoke a series of functions sequentially, such as addToDom
, h1
and echo
. Behind the scenes, it basically links each function in a chain-like Manne by passing the return value of one as input to the next. In this case, the string “Hello World” returned from echo
is passed into h1
,and the result is finally passed into addToDom
.
Why does the functional solution kook this way? I like to think of it as basically parameterizing your code so that you can easily change it in a noninvasive manner — like adjusting an algorithm’s initial conditions. With this foundation laid, you can now easily augment printMessage
to repeat the message twice, use an h2
header, and write to the console instead of the DOM, all without having to rewrite any of the internal logic.
// Listing 1.2 Extending printMessage
var printMessage = run(console.log, repeat(3), h2, echo)
printMessage('Get Functional')
This is visually distinct approach isn’t accidental. When comparing the functional to the nonfunctional solution, you may have noticed that here’s a radical difference in style. Both print the same output, yet they look very different. This is due to FP’s inherent declarative mode of development. In order to fully understand functional programming, you must learn the fundamental concepts on which it’s based:
- Declarative programming
- Pure functions
- Referential transparency
- Immutability
Functional programming is declarative
Functional programming falls under the umbrella of declarative programming paradigms: it’s a paradigm that expresses a set of operations without revealing how they’re implemented or how data flows through them. The more popular models used today, though, are imperative or procedural, and are supported in most structured and object-oriented languages like Java, C#, C++, and others. Imperative programming treats a computer program as merely as a sequence of top-to-bottom statements that changes the state of the system in order to compute a result.
Let’s look at a simple imperative example.
var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for (let i = 0; i < array.length; i++) {
array[i] = Math.pow(array[i], 2)
}
array // -> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Imperative programming tells the computer, in great detail, how to perform a certain task (looping through and applying the square formula to each number, in this case). This is the most common way of writing this code and will most likely be your first approach to tackling this problem.
Declarative programming, on the other hand, separates program description from evaluation. It focuses on the use of expressions to describe what the logic of a program is without necessarily specifying its control flow or state changes. An example of declarative programming is found in SQL statements. SQL queries are composed of statements that describe what the outcome of a query should look like, abstracting the internal mechanism for data retrieval.
Shifting to a functional approach to tackle this same task, you only need to be concerned with applying the right behavior at each element and cede control of looping to other parts of the system. You can let Array.map()
do most of the heavy lifting:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(
function(num) {
return Math.pow(num, 2)
})
// -> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Compared with the previous example, you see that this code frees you from the responsibility properly managing a loop counter and array index access; put simply, the more code you have, the more places there are for bugs to occur. Also, standard loops aren’t reusable artifacts unless they’re abstracted with functions. <!–And that’s precisely what we’ll do. In chapter 3, i demonstrate how to remove manual loops completely from your code in favor of first-class, higher-order functions like map
, reduce
, and filter
, which accept functiosn as parameters so that your code is more reusable, extensible, and delcarative.–>
Abstracting loops with functions lets you take advantage of lambda expressions or arrow functions, introduced in ES6 JavaScript. Lambda expressions provide a succinct alternative to anonymous functions that can be passed in as a function argument, in the spirit of writing less:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(num => Math.pow(num, 2))
// -> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Translating lambda notation to regular function notation
Lambda expressions provide an enormous syntactical advantage over regular function notations because they reduce the structure o a function call down to the most important pieces. This ES6 lambda expression
num => Math.pow(num, 2)
Is equivalent to the following function:
function(num) { return Math.pow(num, 2) }
Why remove loops from your code? A loop is an imperative control structure that’s hard to reuse and difficult to plug in to other operations. In addition, it implies code that’s constantly changing or mutating in response to new iterations. You’ll learn that functional programs aim for statelessness and immutability as much as possible. Stateless code has zero chance of changing or breaking global state. To achieve this, you’ll use functions that avoid side effects and changes of state, known as pure functions.
Pure functions and the problem with side effects
Functional programming is based on the premise that you build immutable programs based on the building blocks of pure functions. A pure function has the following qualities:
- It depends only on the input provided and not on any hidden or external state that may change during its evaluation or between calls.
- It doesn’t indict changes beyond their scope, such as modifying a global object or a parameter passed by reference.
Intuitively, any function that doesn’t meet these requirements is “impure”. Programming with immutability can feel strange at first. After all, the whole point of imperative design, which is what we’re accustomed to, is to declare that variables are to mutate from one statement to the next (they’re “variable,” after all). This is a natural thing for us to do. Consider the following function:
var counter = 0
function increment() {
return ++counter
}
This function is impure because it reads/modifies an external variable, counter
which isn’t local to the function’s scope. Generally, functions have side effects when reading from or writing to external resources. Another example is the popular function Date.now()
; its output certainly isn’t predicable and consistent, because it always depends on a constantly changing factor: time.
Another common side effect occurs when accessing instance data via the this
keyword. The behavior of this
in JavaScript is unlike it is in nay other programming language because it determines the runtime context of a function. This often leads to code that’s hard to reason about, which is why I avoid it when possible. Side effects can occur in many situations, including these:
- Changing a variable, property, or data structure globally
- Changing the original value of a function’s argument
- Processing user input
- Throwing an exception, unless it’s caught within the same function
- Printing to the screen or logging
- Querying the HTML documents browser cookies, or databases
If you’re unable to create and modify objects or print to the console, what practical value would you get from a program like this? Indeed, pure functions can be hard to use in an world full of dynamic behavior and mutation. But practical functional programming doesn’t restrict all changes of state; it just provides a framework to help you manage and reduce them, while allowing you to separate the purposes fro the impure. Impure code produces externally visible side effects like those listed earlier, and in this book I examine ways to deal with this.
To talk more concretely about these issues, suppose you’re a developer on a team implementing an application to manage a school’s student data. Listing 1.3 shows a small imperative program that finds a student record by Social Security number and renders it in the browser (again, the use of the browser is immaterial; you could just as easily write to the console.
// Listing 1.3 Imperative `showStudent` function with side effects
function showStudent(ssn) {
var student = db.get(ssn)
if(student !== null) {
document.querySelector(`#${elementId}`).innerHTML =
`${student.ssn},
${student.firstname},
${student.lastname}`
}
else {
throw new Error('Student not found!')
}
}
showStudent('444-44-4444')
Let’s analyze this code further. This function clearly exposes a few side effects that ripple beyond tis scope:
- It interacts with an external variable (
db
) for data access because the function signature doesn’t declare this parameter. At any point in time, this reference could becomenull
or change from one call to the next, yielding completely different results and compromising the integrity of the program. - The global variable
elementId
can change at any time, outside your control.
The function in listing 1.3 relies on external resources, which make the code flexible, hard to work with, and difficult to test. Pure functions, on the other hand, have clear contracts as part of their signatures that describe clearly all of the function’s formal parameters (set of inputs), making them simpler to understand and use.
Let’s put our functional hat on and use what you learned from the simple printMessage
program against this real-life scenario. As you become more comfortable with functional programming in this book, you’ll continue to improve this implementation with new techniques. At the moment, you can make two simple enhancements:
- Separate this long function into shorter functions, each with a single purpose.
- Reduce the number of side effects by explicitly defining all arguments needed for the functions to carry out their job.
Let’s begin by separating the activities of fetching the student record from displaying it on the screen. Granted, the side effects from interacting with an external storage system and the DOM are unavoidable, but at least you can make them more manageable and single them out from the main logic. To do this, I’ll introduce a popular FP technique called currying. With currying, you can partially set some of the arguments of a function in order to reduce them down to one. As shown in the next listing, you can apply curry
to reduce find
and append
to unary functions that can easily combine via run
.
// Listing 1.4 Decomposing the `showStudent` program
// The find function needs a reference to the object store and the ID of the student to look up.
var find = curry(function (db, id) {
var obj = db.get(id)
if(obj === null) {
throw new Error('Object not found!')
}
return obj
})
// Converts a student object into comma-separated values
var csv = (student) {
return `${studnet.ssn}, ${student.firstname}, ${student.lastname}`
}
// To display a student's details on the page, you need the element ID and the student data.
var append = curry(function (elementId,info) {
document.querySelector(elementId).innerHTML = info
})
You don’t need to understand curling now, but it’s important to see that being able o reduce the length of these functions lets you write showStudent
as the combination of these smaller parts:
var showStudent = run(
append('#student-info'), // Partially set the HTML element ID to use in the function
csv,
find(db))
showStudent('444-44-4444')
Although this program has been only marginally improved, it’s beginning to show many benefits:
- It’s a lot more flexible, because it now has three reusable components.
- This fine-grained function reuse is a strategy for increasing your productivity, because you can dramatically reduce the footprint of code that must be actively managed.
- You enhance the code’s readability by following a declarative style that provides a clear view of the high-level steps carried out by this program.
- More important, interaction with the HTML objects is moved into its own function, isolating the pure from the non-pure (impure) behavior.
This program still has some loose ends that need to be tightened, but reducing side effects will make it less brittle to changing external conditions. If you look closer at the find function, you’ll notice it has a null
-check branching statement that can produce an exception. For many reasons, which we’ll study later, it’s beneficial to guarantee a consistent return value from a function, making its result consistent and predicable. This is a quality of pure functions called referential transparency.
Referential transparency and substitutablity
Referential transparency is a more formal way of defining a pure function. Purity in this sense refers to the existence of a pure mapping between a function’s arguments and its return value. Hence, if a function consistently yields the same result on the same input, it’s said to be referentially transparent. For instance, the stageful Increment
function shown earlier isn’t referentially transparent because its return value is heavily dependent on the external variable counter
. Here it is again:
va counter = 0
function increment() {
return ++counter
}
In order to make it referentially transparent, you need to remove its dependent state — the outer variable —and make it an explicit formal parameter of the function signature. You can convert it to ES6 lambda form:
var increment = counter => counter + 1
Now this function is stable and always returns the same output when provided with the same input. Otherwise, the function’s return value is being influenced by some external factor.
We seek this quality in functions because it not only makes code easier to test, but also allows us to reasons about the entire programs
much more easily. Referential transparency or equational correctness is inherited from math, but functions in programming languages behave nothing like mathematical functions; so achieving referential transparency is strictly on us.Using the magical run
function again, figure 1.2 shows how to sue the imperative versus the functional version of increment
.
Programs built this way are much easier to reason about because you can form a mental model of the state of the system and achieve the desired outcome through rewriting
or substitution
. Let’s look at this more concretely and assume that any program can be defined as a set of functions that processes a given input and produces an output. Here it is in pseudo form:
Progam = [Input] + [func1, func2, func3, ...] -> Output

If the functions [func1, func2, func3, …]
are pure, you an easily rewrite this program by inlining the values produced by them — [val1, val2, val3, …]
— without altering the result. Consider a simple example of computing a student’s average grade:
var input = [80, 90, 100]
var average = (arr) => divide(sum(arr), size(arr))
average (input) // -> 90
Because the functions sum
and size
are referentially transparent, you can easily rewrite this expression for the given input as
var average = divide(270, 3) // -> 90
Because divide
is always pure, it can be rewritten further using its mathematical notation; so for this input, the average is always 270/3=90
. Referential transparency makes it possible to reason about programs in this systematic, almost mathematical, way. The entire program can be implemented as follows:
var sum = (total, current) => total + current
var total = arr => arr.reduce(sum)
var size = arr => arr.length
var divide = (a, b) => a / b
var average = arr => divide(total(arr), size(arr))
average(input) // -> 90
Applying equational reasoning to every program is important to understand that this is implicit in any purely functional program, and that it would be possible if functions had side effects. In chapter 6, I come back to the importance of this principle in the context of unit test functional code. Defining all function arguments up front avoids side effects in most cases, as with scalar values; but when objects are passed by reference, you must be cautious not to inadvertently mutate them.
Preserving immutable data
Immutable data is data that can’t be changed after it’s been created. In JavaScript, as with many other languages, all primitive types (String
, Number
and so on) are inherently immutable. But other objects, like arrays, aren’t immutable; even if they’re appeased as input to a function, you still cause a side effect by changing the original content. Consider this simple array-sorting code:
var sortDesc = function (arr) {
return arr.sort(function (a, b) {
return b - a
}
}
Unfortunately, the Array.sort
function is stageful and causes the side effect of sorting the array in place — the original reference is changed. This is a serious flaw in the language and one that we’ll overcome in future chapters.
Now that you’ve had a glimpse of the fundamental principle behind functional programming (declarative, pure, and immutable), I can express what it is more succinctly: functional programming refers to the declarative evaluation of pure functions to create immutable programs by avoiding externally observable side effects.
Most of the issues JavaScript developers face nowadays are due to the heavy use of large functions that are rely greatly on externally shared variables, do lost of branching, and have no clear structure. Unfortunately, this is the situation for many files that execute together, forming a shared mesh of mutable, global data that can be hard to track and debug.
Being forced to think in terms of pure operations and looking at functions as. Sealed units of works that never mutate data can definitely reduce the potential for bugs. Understanding these core principles is important in order to reap the benefits functional programming brings to your code, which will guide you on the path to overcoming complexity.
Benefits of functional programming
In order to benefit from functional programming, you must learn to think functionally and have the proper tools.In this section, I introduce some core techniques that are indispensable for your toolbox in order to develop your functional awareness — the instinct of looking at problems as a combination of simple functions that together provide a complete solution. The topics introduced in the section also serve as a brief introduction to some of the upcoming chapters in the book.
Now let’s explore at a high level the benefits FP brings to your JavaScript applications. The following subsections explain how it can
- Encourage you to decompose tasks into simple functions
- Process data using fluent chains
- Decrease the complexity of event-driven code by enabling reactive paradigms.
Encouraging the decomposition of complex tasks
At a high level, functional programming is effectively the interplay between decomposition (breaking programs into small pieces) and composition (joining the pieces back together). It’s this duality that makes functional programs modular and so effective. As I mentioned previously, the unit of modularity, or unit of work, is the function itself. Thinking of functionally typically begins with decomposition by learning to break a particular task into logical subtasks (functions), as shown in the decomposition of showStudent
in figure 1.3.

Modularization in FP is closely related to the singularity principle, which states that functions should have a single purpose; this was also evident in the code for average
, shown earlier. Purity and referential transparency encourage you to think this way because in order to glue simple functions together, they must agree on the types of inputs and outputs. From referential transparency, you learn that a function’s complexity is sometimes directly related to the number of arguments it receives (this is merely a partial observation and not a formal concept indicating that the lower the number of function parameters, the simpler the function tends to be).
All along, I’ve been using run
to combine functions to make up whole programs. It’s time to uncover this dark magic. In reality, run
is an alias for the most important techniques: composition. The composition of two functions is another function that results from taking the output of one and plugging it into the next. Assume that you have two functions f
and g
. Formally, this can be expressed as follows:
This formula reads “f
composed of g
“, which creates a loose, type-safe relationship between g
‘s return value and f
‘s argument.The requirement for two functions to be compatible is that they must agree in the number of arguments as well as their types. For now, let’s diagram the composition of showStudent
in figure 1.4, this time using the correct function, compose
:
var showStudent = compose(append('#studnet-info'), csv, find(db))
showStudent('444-44-4444')

Understanding compose
is crucial for learning how to implementing modularity and reusability in functional applications; Functional composition leads to code in which the meaning of the entire expression can be understood from the meaning of its individual pieces — a quality that becomes hard to achieve in other paradigms. (?)
In addition, functional composition raises the level of abstraction so that you can clearly outline all the steps performed in this code without being exposed to any of its underlying details. Because compose
accepts other functions as arguments, it’s known as a higher-order function. But composition isn’t the only way to create fluent, modular code; in this book, you’ll also learn how to build sequences of operations by connecting operations in a chain-like manner.
Processing data using fluent chains
In addition to map
, you can import a repertoire of many higher-order functions into any JavaScript project through some powerful and optimized functional libraries. Many of the higher-order functions implemented in popular JavaScript functional toolkits like Lodash.js and Ramda.js: they overlap in many aspects, but each brings unique features that can facilitate assembling function chains.
If you’ve written some jQuery code before, you’re probably familiar with this idiom. A chain is a sequential invocation of functions that share a common object return value (such as the $
or jQuery
object). Like composition, this idiom allows you to write terse and concise code, and it’s typically used a lot in functional as well as reactive programming Javascript libraries (more on this later). To show this, let’s tackle a different problem.
let enrollment = [
{enrolled: 2, grade: 100},
{enrolled: 2, grade: 80},
{enrolled: 1, grade: 89}
]
an imperative approach might look like this:
var totalGrades = 0
var totalSudentsFound = 0
for (let i = 0; i < enrollment.length; i++) {
let sudent = enrollment [i]
if (student != nul) {
if (student.enrolled > 1) {
totalGrades += students.grade
totalStudentFound++
}
}
}
var average = totalGrades / totalStudentsFound // -> 90
Justas before, decomposing this problem with a functional mindset, you can identify three major steps:
- Selecting the proper set of students
- Extracting their grades
- Calculating their average grade
Now you can use Lodash to stitch together functions representing these steps, forming a function chain, as shown in listing 1.5. A function chain is a lazy evaluated program, which means it defers its execution until needed. This benefits performance because you can avoid executing entire sequences of code that won’t be used anywhere else, saving precious GPU cycles. This effectively simulates the call-by-need
behavior built into other functional languages.
// Listing 1.5 Programming with funtion chains
_.chain(enrollment)
.filter(student => student.enrolled > 1)
.pluck('grade')
.average()
.value() // -> 90 // Calling `_.value()` kicks off the execution of all opeartions in the chain.
Don’t be too concerned at this point with everything that’s happening in this code. For now, compare it to the imperative version, and notice how you can eliminate the need to declare and change variables, loops, and if-else
statements.
To be fair, though, this example skip a lot of error-handling code found in typical real-world programs. Earlier, I mentioned that throwing exceptions was a cause of side effects. Exception don’t exist in academic functional programming, but in real life you won’t be able to escape them. There’s a distinction between pure error handling and exception handling. The goal is to implement pure error handling as much as possible and allow exceptions to fire ini truly exceptional conditions, just like the ones described earlier.
Fortunately, by applying some purely functional design patterns, you won’t need to sacrifice this level of expressiveness to provide robust error-handling logic for your code.
So far, you’ve seen how FP can help you create modular, testable, extensible applications. How well does it work when you need to interact with asynchronous or event-based data coming from user input, remote web requests, file systems, or persistent storage?
Reacting to the complexity of asynchronous applications
If you remember the lat time you had to fetch remote data, handle user input, or interact with local storage, you probably recall writing entire sections of business logic into nested sequences of callback functions. This callback pattern breaks the linear flow of your code and become hard to read, because it’s cluttered with nested forms of success- and error-handling logic. This is all about to change.
As I said earlier, learning functional programming, especially for JavaScript developers, is extremely important today. When building large applications, a lot of the focus shifted from object-oriented frameworks like Backbone.js to frameworks that favor a reactive programming paradigm. Web frameworks like Angular.js are still widely used today; but new players in the field, such as RxJS, embrace the power of FP to tackle very challenging tasks.
Reactive programming is probably one of the most exciting and interesting applications of functional programming. You can use it to dramatically reduce the complexity in asynchronous and event-driven code that you, as JavaScript developers, deal with on a daily basis on the client as well as the server.
The main benefit of adopting a reactive paradigm is that it raises the level of abstraction of your code, allowing you to focus specific business logic while forgetting about the arduous boilerplate code associated with setting up asynchronous and ting about the arduous boilerplate code associated with setting up asynchronous and event-based programs. Also, this emerging paradigm takes full advantage of FP’s ability to chain or compose functions together.
Events come in many flavors: mouse clicks, text field changes, focus changes, handling new HTTP requests, database queries, file writes, and so on. Suppose you need to read and validate a student’s SSN. A typical imperative approach might look like the next listing.
// Listing 1.6 Imperative program that reads and validates a student's SSN
var valid = false
var elem = document.querySelector('#student-ssn')
elem.onkeyup = function(event) {
var val = elem.value
if(val !== null && val.length !== 0) {
val = val.replace(/^\s*|\s*$|\-s/g, '')
if(val.length == 9) {
console.log(`Valid SSN: ${val}!`)
valid = true
}
}
else {
console.log(`Invalid SSN: ${val}!`)
}
}
For such a simple task, this is beginning to look complex; and the code lacks the desired level of modularity with all business logic in a single place. Also, this function isn’t releasable due to its dependency on external state. Because reactive programming is based on function programming, it benefits from the use of pure functions to process data with the same familiar operations like map
and reduce
and the terseness of lambda expressions. So learning functional is half the battle when learning reactive! This paradigm is enabled through a very important artifact called an observable. Observables let you subscribe to a stream of data that you can process by composing and chaining operation together elegantly. Let’s see it in action and subscribe to a simple input field for a student’s SSN.
// Listing 1.7 Functional program that reads and validates a student's SSN
Rx.Observable.fromEvent(document.querySelector('#student-ssn'), 'keyup')
.map(input => input.srcElement.value)
.filter(ssn => ssn !== null && ssn.lenth !== 0)
.map(ssn => ssn.replace(/^\s*|\s*$|\-/g, ''))
.skipWhile(ssn => ssn.length !== 9)
.subscribe(
validSsn => console.log(`Valid SSN ${validSsn}`)
)
Can you see the similarity between listing 1.7 and programming with chains in listing 1.5? This shows that whether you’re processing a collection of elements or user input, it’s all abstracted out and treated in the exact same manner. I have much more to say about this input in chapter 8.
One of the most important takeaways is that all the operations performed in listing 1.7 are completely immutable, and all the business logic is segregated into individual functions. You don’t have to use functional with reactive, but thinking functionally forces
you to do — and when you do, you unlock a truly amazing architecture based on _functional reactive programming_ (FRP).
Functional programming is a paradigm shift that can dramatically transform the way you tackle solutions to any programming challenges. So is FP a replacement for the more popular object-oriented design? Fortunately, applying functional programming to your code isn’t an all-or-nothing approach. In fact, lists of applications can benefit from using FP alongside an object-oriented architecture. Due to rigid control for imitability and shared state, FP is also known for making multithreaded programming more straightforward. Because JavaScript is a single-threaded platform, this isn’t something we need to working about or cover in this book. In the next chapter, I spend some time highlighting some of the key differences between functional and object-oriented design, which I believe will help you grok the functional way of thinking more easily.