Home Web Development Mastering JavaScript Functional Programming - Second Edition

Mastering JavaScript Functional Programming - Second Edition

By Federico Kereki
books-svg-icon Book
eBook $26.99 $17.99
Print $38.99
Subscription $15.99 $10 p/m for three months
$10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
BUY NOW $10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
eBook $26.99 $17.99
Print $38.99
Subscription $15.99 $10 p/m for three months
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
  1. Free Chapter
    Becoming Functional - Several Questions
About this book
Functional programming is a paradigm for developing software with better performance. It helps you write concise and testable code. To help you take your programming skills to the next level, this comprehensive book will assist you in harnessing the capabilities of functional programming with JavaScript and writing highly maintainable and testable web and server apps using functional JavaScript. This second edition is updated and improved to cover features such as transducers, lenses, prisms and various other concepts to help you write efficient programs. By focusing on functional programming, you’ll not only start to write but also to test pure functions, and reduce side effects. The book also specifically allows you to discover techniques for simplifying code and applying recursion for loopless coding. Gradually, you’ll understand how to achieve immutability, implement design patterns, and work with data types for your application, before going on to learn functional reactive programming to handle complex events in your app. Finally, the book will take you through the design patterns that are relevant to functional programming. By the end of this book, you’ll have developed your JavaScript skills and have gained knowledge of the essential functional programming techniques to program effectively.
Publication date:
January 2020
Publisher
Packt
Pages
470
ISBN
9781839213069

 

Becoming Functional - Several Questions

Functional programming (or FP) has been around since the earliest days of computing, and is going through a sort of revival because of its increased use with several frameworks and libraries, most particularly in JavaScript (JS). In this chapter, we shall do the following:

  • Introduce some concepts of FP to give a small taste of what it means.
  • Show the benefits (and problems) implied by the usage of FP and why we should use it.
  • Start thinking about why JavaScript can be considered an appropriate language for FP.
  • Go over the language features and tools that you should be aware of in order to fully take advantage of everything in this book.

By the end of this chapter, you'll have the basic tools that we'll be using in the rest of the book, so let's get started by learning about functional programming.

 

What is functional programming?

If you go back in computer history, you'll find that the second oldest programming language still in use, Lisp, is based on FP. Since then, there have been many more functional languages, and FP has been applied more widely. But even so, if you ask people what FP is, you'll probably get two widely dissimilar answers.

For trivia or history buffs, the oldest language still in use is Fortran, which appeared in 1957, a year before Lisp. Quite shortly after Lisp came another long-lived language, COBOL, for business-oriented programming.

Depending on whom you ask, you'll either learn that it's a modern, advanced, enlightened approach to programming that leaves every other paradigm behind or that it's mainly a theoretical thing, with more complications than benefits, practically impossible to implement in the real world. And, as usual, the real answer is not in the extremes, but somewhere in between. Let's start by looking at the theory versus practice and see how we plan to use FP. 

Theory versus practice

In this book, we won't be going about FP in a theoretical way. Instead, our point is to show you how some of its techniques and tenets can be successfully applied for common, everyday JavaScript programming. But—and this is important—we won't be going about this in a dogmatic fashion, but in a very practical way. We won't dismiss useful JavaScript constructs simply because they don't happen to fulfill the academic expectations of FP. Similarly, we won't avoid practical JavaScript features just to fit the FP paradigm. In fact, we could almost say that we'll be doing Sorta Functional Programming (SFP) because our code will be a mixture of FP features, more classical imperative ones, and object-oriented programming (OOP).

Be careful, though: what we just said doesn't mean that we'll be leaving all the theory by the side. We'll be picky, and just touch the main theoretical points, learn some vocabulary and definitions, and explain core FP concepts, but we'll always be keeping in sight the idea of producing actual, useful JavaScript code, rather than trying to meet some mystical, dogmatic FP criteria.

OOP has been a way to solve the inherent complexity of writing large programs and systems, and developing clean, extensible, scalable application architectures; however, because of the scale of today's web applications, the complexity of all codebases is continuously growing. Also, the newer features of JavaScript make it possible to develop applications that wouldn't even have been possible just a few years ago; think of mobile (hybrid) apps that are made with Ionic, Apache Cordova, or React Native or desktop apps that are made with Electron or NW.js, for example. JavaScript has also migrated to the backend with Node.js, so today, the scope of usage for the language has grown in a serious way that deals with all the added complexity of modern designs.

A different way of thinking

FP is a different way of writing programs, and can sometimes be difficult to learn. In most languages, programming is done in an imperative fashion: a program is a sequence of statements, executed in a prescribed fashion, and the desired result is achieved by creating objects and manipulating them, which usually means modifying the objects themselves. FP is based on producing the desired result by evaluating expressions built out of functions that are composed together. In FP, it's common to pass functions around (such as passing parameters to other functions or returning functions as the result of a calculation), to not use loops (opting for recursion instead), and to skip side effects (such as modifying objects or global variables).

In other words, FP focuses on what should be done, rather than on how. Instead of worrying about loops or arrays, you work at a higher level, considering what you need to be done. After becoming accustomed to this style, you'll find that your code becomes simpler, shorter, and more elegant, and can be easily tested and debugged. However, don't fall into the trap of considering FP as the goal! Think of FP only as a means to an end, as with all software tools. Functional code isn't good just for being functional, and writing bad code is just as possible with FP as with any other technique!

What FP is not

Since we have been saying some things about what FP is, let's also clear up some common misconceptions, and look at what FP is not:

  • FP isn't just an academic ivory tower thing: It is true that the lambda calculus upon which it is based was developed by Alonzo Church in 1936 as a tool to prove an important result in theoretical computer science (which preceded modern computer languages by more than 20 years!); however, FP languages are being used today for all kinds of systems.
  • FP isn't the opposite of object-oriented programming (OOP): It isn't a case of choosing declarative or imperative ways of programming. You can mix and match as best suits you, and we'll be doing this throughout this book, bringing together the best of all worlds. 
  • FP isn't overly complex to learn: Some of the FP languages are rather different from JavaScript, but the differences are mostly syntactic. Once you learn the basic concepts, you'll see that you can get the same results in JavaScript as with FP languages.

It may also be relevant to mention that several modern frameworks, such as the React and Redux combination, include FP ideas.

For example, in React, it's said that the view (whatever the user gets to see at a given moment) is a function of the current state. You use a function to compute what HTML and CSS must be produced at each moment, thinking in a black-box fashion.

Similarly, in Redux you have the concept of actions that are processed by reducers. An action provides some data, and a reducer is a function that produces the new state for the application in a functional way out of the current state and the provided data. 

So, both because of the theoretical advantages (we'll be getting to those in the following section) and the practical ones (such as getting to use the latest frameworks and libraries), it makes sense to consider FP coding. Let's get on with it.

 

Why use FP?

Throughout the years, there have been many programming styles and fads. However, FP has proven quite resilient and is of great interest today. Why would you want to use FP? The question should rather first be, what do you want to get? and only then, does FP get you that? Let's answer these important questions in the following sections.

What we need

We can certainly agree that the following list of concerns is universal. Our code should have the following qualities:

  • Modular: The functionality of your program should be divided into independent modules, each of which contains what it needs to perform one aspect of the program's functionality. Changes in a module or function shouldn't affect the rest of the code.
  • Understandable: A reader of your program should be able to discern its components, their functions, and their relationships without undue effort. This is closely linked with the maintainability of the code; your code will have to be maintained at some time in the future, whether to be changed or to have new functionality added.
  • Testable: Unit tests try out small parts of your program, verifying their behavior independently of the rest of the code. Your programming style should favor writing code that simplifies the job of writing unit tests. Unit tests are also like documentation in that they can help readers understand what the code is supposed to do.
  • Extensible: It's a fact that your program will someday require maintenance, possibly to add new functionality. Those changes should impact the structure and data flow of the original code only minimally (if at all). Small changes shouldn't imply large, serious refactoring of your code.
  • Reusable: Code reuse has the goal of saving resources, time, and money, and reducing redundancy by taking advantage of previously written code. There are some characteristics that help this goal, such as modularity (which we already mentioned), high cohesion (all the pieces in a module belong together), low coupling (modules are independent of each other), separation of concerns (the parts of a program should overlap in functionality as little as possible), and information hiding (internal changes in a module shouldn't affect the rest of the system).

What we get

So does FP give you the five characteristics we just listed in the previous section?

  • In FP, the goal is to write separate independent functions that are joined together to produce the final results.
  • Programs that are written in a functional style usually tend to be cleaner, shorter, and easier to understand.
  • Functions can be tested on their own, and FP code has advantages in achieving this.
  • You can reuse functions in other programs because they stand on their own, not depending on the rest of the system. Most functional programs share common functions, several of which we'll be considering in this book.
  • Functional code is free from side effects, which means you can understand the objective of a function by studying it without having to consider the rest of the program.

Finally, once you get used to the FP style of programming, code becomes more understandable and easier to extend. So it seems that all five characteristics can be achieved with FP!

For a well-balanced look at the reasons to use FP, I'd suggest reading Why Functional Programming Matters, by John Hughes; it's available online at www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf. It's not geared towards JavaScript, but the arguments are easily understandable, anyway.

Not all is gold

However, let's strive for a bit of balance. Using FP isn't a silver bullet that will automagically make your code better. Some FP solutions are actually tricky, and there are developers who greatly enjoy writing code and then asking, what does this do? If you aren't careful, your code may become write-only and practically impossible to maintain; there goes understandable, extensible, and reusable out the door!

Another disadvantage is that you may find it harder to find FP-savvy developers. (Quick question: how many functional programmers sought job ads have you ever seen?) The vast majority of today's web code is written in imperative, non-functional ways, and most coders are used to that way of working. For some, having to switch gears and start writing programs in a different way may prove an unpassable barrier. 

Finally, if you try to go fully functional, you may find yourself at odds with JavaScript, and simple tasks may become hard to do. As we said at the beginning, we'll opt for sorta FP, so we won't be drastically rejecting any language features that aren't 100% functional. After all, we want to use FP to simplify our coding, not to make it more complex!

So, while I'll strive to show you the advantages of going functional in your code, as with any change, there will always be some difficulties. However, I'm fully convinced that you'll be able to surmount them and that your organization will develop better code by applying FP. Dare to change! So, given that you accept that FP may apply to your own problems, let's now consider the other question, can we use JavaScript in a functional way and is it appropriate?

 

Is JavaScript functional?

At about this time, there is another important question that you should be asking: Is JavaScript a functional language? Usually, when thinking about FP, the list of languages that are mentioned does not include JavaScript, but does include less common options, such as Clojure, Erlang, Haskell, and Scala; however, there is no precise definition for FP languages or a precise set of features that such languages should include. The main point is that you can consider a language to be functional if it supports the common programming style associated with FP. Let's start by learning about why we would want to use JavaScript at all and how the language has evolved to its current version, and then see some of the key features that we'll be using to work in a functional way.

JavaScript as a tool

What is JavaScript? If you consider popularity indices, such as the ones at www.tiobe.com/tiobe-index/ or http://pypl.github.io/PYPL.html, you'll find that JavaScript is consistently in the top ten most popular languages. From a more academic point of view, the language is sort of a mixture, borrowing features from several different languages. Several libraries helped the growth of the language by providing features that weren't so easily available, such as classes and inheritance (today's version of the language does support classes, but that was not the case not too long ago), that otherwise had to be achieved by doing some prototype tricks.

The name JavaScript was chosen to take advantage of the popularity of Java—just as a marketing ploy! Its first name was Mocha, then, LiveScript, and only then, JavaScript.

JavaScript has grown to be incredibly powerful. But, as with all power tools, it gives you a way to not only produce great solutions, but also to do great harm. FP could be considered as a way to reduce or leave aside some of the worst parts of the language and focus on working in a safer, better way; however, due to the immense amount of existing JavaScript code, you cannot expect it to facilitate large reworkings of the language that would cause most sites to fail. You must learn to live with the good and the bad, and simply avoid the latter parts.

In addition, the language has a broad variety of available libraries that complete or extend the language in many ways. In this book, we'll be focusing on using JavaScript on its own, but we will make references to existing, available code.

If we ask whether JavaScript is actually functional, the answer will be, once again, sorta. It can be seen as functional because of several features, such as first-class functions, anonymous functions, recursion, and closures—we'll get back to this later. On the other hand, it also has plenty of non-FP aspects, such as side effects (impurity), mutable objects, and practical limits to recursion. So, when programming in a functional way, we'll be taking advantage of all the relevant, appropriate language features, and we'll try to minimize the problems caused by the more conventional parts of the language. In this sense, JavaScript will or won't be functional, depending on your programming style!

If you want to use FP, you should decide which language to use; however, opting for fully functional languages may not be so wise. Today, developing code isn't as simple as just using a language; you will surely require frameworks, libraries, and other sundry tools. If we can take advantage of all the provided tools but at the same time introduce FP ways of working in our code, we'll be getting the best of both worlds, never mind whether JavaScript is functional!

Going functional with JavaScript

JavaScript has evolved through the years, and the version we'll be using is (informally) called JS10, and (formally) ECMAScript 2019, usually shortened to ES2019 or ES10; this version was finalized in June 2019. The previous versions were as follows:

  • ECMAScript 1, June 1997
  • ECMAScript 2, June 1998, which was basically the same as the previous version
  • ECMAScript 3, December 1999, with several new functionalities
  • ECMAScript 5, December 2009 (and no, there never was an ECMAScript 4, because it was abandoned)
  • ECMAScript 5.1, June 2011
  • ECMAScript 6 (or ES6; later renamed ES2015), June 2015
  • ECMAScript 7 (also ES7, or ES2016), June 2016
  • ECMAScript 8 (ES8 or ES2017), June 2017
  • ECMAScript 9 (ES9 or ES2018), June 2018
ECMA originally stood for European Computer Manufacturers Association, but nowadays the name isn't considered an acronym anymore. The organization is responsible for more standards other than JavaScript, including JSON, C#, Dart, and others. For more details, go to its site at www.ecma-international.org/.

You can read the standard language specification at www.ecma-international.org/ecma-262/7.0/. Whenever we refer to JavaScript in the text without further specification, ES10 (ES2019) is what is being referred to; however, in terms of the language features that are used in the book, if you were just to use ES2015, then you'd mostly have no problems with this book

No browsers fully implement ES10; most provide an older version, JavaScript 5 (from 2009), with an (always growing) smattering of features from ES6 up to ES10. This will prove to be a problem, but fortunately, a solvable one; we'll get to this shortly. We'll be using ES10 throughout the book.

In fact, there are only a few differences between ES2016 and ES2015, such as the Array.prototype.includes method and the exponentiation operator, **. There are more differences between ES2017 and ES2016—such as async and await, some string padding functions, and more—but they won't impact our code. We will also be looking at alternatives for even more modern additions, such as flatMap(), in later chapters.

As we are going to work with JavaScript, let's start by considering its most important features that pertain to our FP goals.

Key features of JavaScript

JavaScript isn't a purely functional language, but it has all the features that we need for it to work as if it were. The main features of the language that we will be using are as follows: 

  • Functions as first-class objects
  • Recursion
  • Arrow functions
  • Closures
  • Spread

Let's see some examples of each one and find out why they will be useful to us. Keep in mind, though, that there are more features of JavaScript that we will be using; the upcoming sections just highlight the most important features in terms of what we will be using for FP.

Functions as first-class objects

Saying that functions are first-class objects (also called first-class citizens) means that you can do everything with functions that you can do with other objects. For example, you can store a function in a variable, you can pass it to a function, you can print it out, and so on. This is really the key to doing FP; we will often be passing functions as parameters (to other functions) or returning a function as the result of a function call. 

If you have been doing async Ajax calls, then you have already been using this feature: a callback is a function that will be called after the Ajax call finishes and is passed as a parameter. Using jQuery, you could write something like the following:

$.get("some/url", someData, function(result, status) {
// check status, and do something
// with the result
});

The $.get() function receives a callback function as a parameter and calls it after the result is obtained. 

This is better solved, in a more modern way, by using promises or async/await, but for the sake of our example, the older way is enough. We'll be getting back to promises, though, in the section called Building better containers in Chapter 12Building Better Containers – Functional Data Types, when we discuss monads; in particular, see the section called Unexpected Monads - Promises.

Since functions can be stored in variables, you could also write something like the following. Pay attention to how we use the doSomething variable in the $.get(...) call:

var doSomething = function(result, status) {
// check status, and do something
// with the result
};

$.get("some/url", someData, doSomething);

We'll be seeing more examples of this in Chapter 6, Producing Functions – Higher-Order Functions.

Recursion

Recursion is the most potent tool for developing algorithms and a great aid for solving large classes of problems. The idea is that a function can at a certain point call itself, and when that call is done, continue working with whatever result it has received. This is usually quite helpful for certain classes of problems or definitions. The most often quoted example is the factorial function (the factorial of n is written as n!) as defined for nonnegative integer values:

  • If n is 0, then n!=1
  • If n is greater than 0, then n! = n * (n-1)!
The value of n! is the number of ways that you can order n different elements in a row. For example, if you want to place five books in line, you can pick any of the five for the first place, and then order the other four in every possible way, so 5! = 5*4!. If you continue to work this example, you'll get 5! = 5*4*3*2*1=120, so n! is the product of all numbers up to n.

This can be immediately turned into code:

function fact(n) {
if (n === 0) {
return 1;

} else {
return n * fact(n - 1);
}
}

console.log(fact(5)); // 120

Recursion will be a great aid for the design of algorithms. By using recursion, you could do without any while or for loops—not that we want to do that, but it's interesting that we can! We'll be devoting the entirety of Chapter 9Designing Functions – Recursion, to designing algorithms and writing functions recursively.

Closures

Closures are a way to implement data hiding (with private variables), which leads to modules and other nice features. The key concept of closures is that when you define a function, it can refer to not only its own local variables but also to everything outside of the context of the function. We can write a counting function that will keep its own count by means of a closure:

function newCounter() {
let count = 0;
return function() {
count++;
return count;
};
}

const nc = newCounter();
console.log(nc()); // 1
console.log(nc()); // 2
console.log(nc()); // 3

Even after newCounter() exits, the inner function still has access to count, but that variable is not accessible to any other parts of your code.

This isn't a very good example of FP— a function (nc(), in this case) isn't expected to return different results when called with the same parameters!

We'll find several uses for closures, such as memoization (see Chapter 4, Behaving Properly – Pure Functions, and Chapter 6, Producing Functions – Higher-Order Functions) and the module pattern (see Chapter 3, Starting out with Functions – A Core Concept, and Chapter 11, Implementing Design Patterns – The Functional Way), among others.

Arrow functions

Arrow functions are just a shorter, more succinct way of creating an (unnamed) function. Arrow functions can be used almost everywhere a classical function can be used, except that they cannot be used as constructors. The syntax is either (parameter, anotherparameter, ...etc) => { statements } or (parameter, anotherparameter, ...etc) => expression. The first allows you to write as much code as you want, and the second is short for { return expression }. We could rewrite our earlier Ajax example as follows:

$.get("some/url", data, (result, status) => {
// check status, and do something
// with the result
});

A new version of the factorial code could be like the following code:

const fact2 = n => {
if (n === 0) {
return 1;

} else {
return n * fact2(n - 1);
}
};
console.log(fact2(5)); // also 120
Arrow functions are usually called anonymous functions because of their lack of a name. If you need to refer to an arrow function, you'll have to assign it to a variable or object attribute, as we did here; otherwise, you won't be able to use it. We'll learn more about this in the section called Arrow functions in Chapter 3, Starting out with Functions - A Core Concept.

You would probably write the latter as a one-liner—can you see the equivalence to our earlier code? Using a ternary operator in lieu of an if is quite common:

const fact3 = n => (n === 0 ? 1 : n * fact3(n - 1));

console.log(fact3(5)); // again 120

With this shorter form, you don't have to write return—it's implied.

In lambda calculus, a function such as x => 2*x would be represented as λx.2*x. Although there are syntactical differences, the definitions are analogous. Functions with more parameters are a bit more complicated; (x,y)=>x+y would be expressed as λx.λy.x+y. We'll learn more about this in the section called Lambdas and functions, in Chapter 3Starting out with Functions - A Core Concept, and in the section called Currying, in Chapter 7Transforming Functions - Currying and Partial Application.

There's one other small thing to bear in mind: when the arrow function has a single parameter, you can omit the parentheses around it. I usually prefer leaving them, but I've applied a JS beautifier, Prettier, to the code, which removes them. It's really up to you whether to include them or not! (For more on this tool, check out https://github.com/prettier/prettier.) By the way, my options for formatting were --print-width 75 --tab-width 2 --no-bracket-spacing.

Spread

The spread operator (see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Spread_operator) lets you expand an expression in places where you would otherwise require multiple arguments, elements, or variables. For example, you can replace arguments in a function call, as shown in the following code:

const x = [1, 2, 3];

function sum3(a, b, c) {
return a + b + c;
}

const y = sum3(...x); // equivalent to sum3(1,2,3)
console.log(y); // 6

You can also create or join arrays, as shown in the following code:

const f = [1, 2, 3];

const g = [4, ...f, 5]; // [4,1,2,3,5]

const h = [...f, ...g]; // [1,2,3,4,1,2,3,5]

It works with objects too:

const p = { some: 3, data: 5 };

const q = { more: 8, ...p }; // { more:8, some:3, data:5 }

You can also use it to work with functions that expect separate parameters instead of an array. Common examples of this would be Math.min() and Math.max():

const numbers = [2, 2, 9, 6, 0, 1, 2, 4, 5, 6];
const minA = Math.min(...numbers); // 0

const maxArray = arr => Math.max(...arr);
const maxA = maxArray(numbers); // 9

You can also write the following equality since the .apply() method requires an array of arguments, but .call() expects individual arguments:

someFn.apply(thisArg, someArray) === someFn.call(thisArg, ...someArray);
If you have problems remembering what arguments are required by .apply() and .call(), this mnemonic may help: A is for an array, and C is for a comma. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call for more information.

Using the spread operator helps write a shorter, more concise code, and we will be taking advantage of it. We have seen all of the most important JavaScript features that we will be using. Let's round off the chapter by looking at some tools that we'll be working with.

 

How do we work with JavaScript?

This is all well and good, but as we mentioned before, it so happens that the JavaScript version available almost everywhere isn't ES10, but rather the earlier JS5. An exception to this is Node.js. It is based on Chrome's v8 high-performance JavaScript engine, which already has several ES10 features available. Nonetheless, as of today, ES10 coverage isn't 100% complete, and there are features that you will miss. (Check out https://nodejs.org/en/docs/es6/ for more on Node.js and v8.) This will surely change in the future, as Internet Explorer will fade away, and the newest Microsoft's browser will share Chrome's engine, but for the time being, we must still deal with older, less powerful engines.

So what can you do if you want to code using the latest version, but the available one is an earlier, poorer one? Or what happens if most of your users are using older browsers, which don't support the fancy features you're keen on using? Let's see some solutions for this.

If you want to be sure of your choices before using any given new feature, check out the compatibility table at https://kangax.github.io/compat-table/es6/ (see Figure 1.1). For Node.js specifically, check out http://node.green/.
Figure 1.1. - The latest JavaScript features may not be widely and fully supported, so you'll have to check before using them.

Using transpilers

In order to get out of this availability and compatibility problem, there are a couple of transpilers that you can use. Transpilers take your original ES10 code, which might use the most modern JavaScript features, and transforms it into equivalent JS5 code. It's a source-to-source transformation, instead of a source-to-object code that would be used in compilation. You can code using advanced ES10 features, but the user's browsers will receive JS5 code. A transpiler will also let you keep up with upcoming versions of the language, despite the time needed by browsers to adopt new standards across desktop and mobile devices.

If you wonder where the word transpiler came from, it is a portmanteau of translate and compiler. There are many such combinations in technological speak: email (electronic and mail), emoticon (emotion and icon), malware (malicious and software), or alphanumeric (alphabetic and numeric), and many more.

The most common transpilers for JavaScript are Babel (at https://babeljs.io/) and Traceur (at https://github.com/google/traceur-compiler). With tools such as npm or webpack, it's fairly easy to configure things so that your code will get automatically transpiled and provided to end-users. You can also carry out transpilation online; see Figure 1.2 for an example of this using Babel's online environment:

Figure 1.2 - The Babel transpiler converts ES10 code into compatible JS5 code

If you prefer Traceur, you can use its tool at https://google.github.io/traceur-compiler/demo/repl.html# instead, but you'll have to open a developer console to see the results of your running code (see Figure 1.3 for an example of transpiled code). Select the EXPERIMENTAL option to fully enable ES10 support:

Figure 1.3 - The Traceur transpiler is an equally valid alternative for ES10-to-JS5 translation
Using transpilers is also a great way to learn new language features. Just type in some code on the left and see the equivalent code on the right. Alternatively, you can use the command-line interface (CLI) tools to transpile a source file and then inspect the produced output.

There's a final possibility that you may want to consider: instead of JavaScript, opt for Microsoft's TypeScript (at http://www.typescriptlang.org/), a superset of the language that is itself compiled to JS5. The main advantage of TypeScript is the ability to add (optional) static type checks to JavaScript, which helps detect certain programming errors at compile time. But beware: as with Babel or Traceur, not all of ES10 will be available.

You can also perform type checks without using TypeScript by using Facebook's Flow (see https://flow.org/).

If you opt to go with TypeScript, you can also test it online at their playground (see http://www.typescriptlang.org/play/). You can set options to be more or less strict with data type checks, and you can also run your code on the spot (see Figure 1.4 for more details):

Figure 1.4 - TypeScript adds type-checking features for safer programming

By using TypeScript, you will be able to avoid common type-related mistakes. A positive trend is that most tools (frameworks, libraries, and so on) are slowly going in this direction, so work will be easier.

Working online

There are some more online tools that you can use to test out your JavaScript code. Check out JSFiddle (at https://jsfiddle.net/), CodePen (at https://codepen.io/), and JSBin (at http://jsbin.com/), among others. You may have to specify whether to use Babel or Traceur; otherwise, newer language features will be rejected. You can see an example of JSFiddle in Figure 1.5:

Figure 1.5 - JSFiddle lets you try out modern JavaScript code (plus HTML and CSS) without requiring any other tools

Using these tools provides a very quick way to try out code or do small experiments—and I can truly vouch for this since I've tested much of the code in the book in this way!

Testing

 

Summary

In this chapter, we have seen the basics of FP, a bit of its history, its advantages (and also some possible disadvantages, to be fair), why we can apply it in JavaScript (which isn't usually considered a functional language), and what tools we'll need in order to go through the rest of this book.

In Chapter 2Thinking Functionally - A First Example, we'll go over an example of a simple problem, look at it in common ways, and end by solving it in a functional manner and analyzing the advantages of our method.

 

Questions

1.1. Classes as first-class objects: We learned that functions are first-class objects, but did you know that classes also are? (Though, of course, speaking of classes as objects does sound weird.) Look at the following example and see what makes it tick! Be careful: there's some purposefully weird code in it:

const makeSaluteClass = term =>
class {
constructor(x) {
this.x = x;
}

salute(y) {
console.log(`${this.x} says "${term}" to ${y}`);
}
};

const Spanish = makeSaluteClass("HOLA");
new Spanish("ALFA").salute("BETA");
// ALFA says "HOLA" to BETA

new (makeSaluteClass("HELLO"))("GAMMA").salute("DELTA");
// GAMMA says "HELLO" to DELTA

const fullSalute = (c, x, y) => new c(x).salute(y);
const French = makeSaluteClass("BON JOUR");
fullSalute(French, "EPSILON", "ZETA");
// EPSILON says "BON JOUR" to ZETA

1.2. Factorial errors: Factorials, as we defined them, should only be calculated for non-negative integers; however, the function that we wrote in the Recursion section doesn't verify whether its argument is valid. Can you add the necessary checks? Try to avoid repeated, redundant tests!

1.3. Climbing factorial: Our implementation of a factorial starts by multiplying by n, then by n-1, then n-2, and so on in what we could call a downward fashion. Can you write a new version of the factorial function that will loop upwards?

1.4. Code squeezing: Not that it's a goal in itself, but by using arrow functions and some other JavaScript features, you can shorten newCounter() to half its length. Can you see how?

About the Author
  • Federico Kereki

    Federico Kereki is a Uruguayan Systems Engineer, with a Master's degree in Education, and over 30 years of experience as a consultant, system developer, and writer. Currently a Subject Matter Expert at Globant, he has taught at Universidad de la República, Universidad ORT Uruguay, and Universidad de la Empresa. He has written articles and booklets on programming, web development, security, and open source topics for blogs, magazines, and websites. He has also written several books, including Modern JavaScript Web Development Cookbook and the upcoming Data Structures and Algorithms in JavaScript. He resides, works, and teaches in Uruguay, but he wrote the first edition of this book while working in India, and the second edition during a sojourn in Mexico.

    Browse publications by this author
Latest Reviews (5 reviews total)
Cursos muito bons, atualizados, profissionais feras.
Es seguro el proceso de compra
Excellent book. Thoroughly enjoyable and lots to learn. Extremely practical
Mastering JavaScript Functional Programming - Second Edition
Unlock this book and the full library FREE for 7 days
Start now