Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Mastering JavaScript Functional Programming
Mastering JavaScript Functional Programming

Mastering JavaScript Functional Programming: Write clean, robust, and maintainable web and server code using functional JavaScript and TypeScript , Third Edition

eBook
€20.98 €29.99
Paperback
€37.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning
Table of content icon View table of contents Preview book icon Preview Book

Mastering JavaScript Functional Programming

Thinking Functionally – A First Example

In Chapter 1, Becoming Functional, we went over what FP is, mentioned some advantages of applying it, and listed some tools we’d need in JavaScript. For now, let’s leave the theory behind and start by considering a simple problem and how to solve it in a functional way.

In this chapter, we will do the following:

  • Look at a simple, e-commerce-related problem
  • Consider several usual ways to solve it (with their associated defects)
  • Find a way to solve the problem by looking at it functionally
  • Devise a higher-order solution that can be applied to other problems
  • Work out how to carry out unit testing for functional solutions

In future chapters, we’ll be returning to some of the topics listed here, so we won’t be going into too much detail. We’ll just show how FP can give a different outlook on our problem and leave further details for later.

After working through this chapter, you will have had a first look at a common problem and at a way of solving it by thinking functionally, as a prelude for the rest of this book.

Our problem – doing something only once

Let’s consider a simple but common situation. You have developed an e-commerce site; the user can fill their shopping cart, and in the end, they must click on a Bill me button so that their credit card will be charged. However, the user shouldn’t click twice (or more), or they will be billed several times.

The HTML part of your application might have something like this somewhere:

<button id="billButton"
    onclick="billTheUser(some, sales, data)">Bill me
      </button>

And, among the scripts, you’d have something similar to the following code:

function billTheUser(some, sales, data) {
  window.alert("Billing the user...");
  // actually bill the user
}

A bad example

Assigning the events handler directly in HTML, the way I did it, isn’t recommended. Instead, unobtrusively, you should set the handler through code. So, do as I say, not as I do!

This is a bare-bones explanation of the web page problem, but it’s enough for our purposes. Now, let’s get to thinking about ways of avoiding repeated clicks on that button. How can we manage to prevent the user from clicking more than once? That’s an interesting problem, with several possible solutions – let’s start by looking at bad ones!

How many ways can you think of to solve our problem? Let’s go over several solutions and analyze their quality.

Solution 1 – hoping for the best!

How can we solve the problem? The first solution may seem like a joke: do nothing, tell the user not to click twice, and hope for the best! Your page might look like Figure 2.1:

Figure 2.1 – An actual screenshot of a page, just warning you against clicking more than once

Figure 2.1 – An actual screenshot of a page, just warning you against clicking more than once

This is a way to weasel out of the problem; I’ve seen several websites that just warn the user about the risks of clicking more than once and do nothing to prevent the situation. So, the user got billed twice? We warned them... it’s their fault!

Your solution might simply look like the following code:

<button
  id="billButton"
  onclick="billTheUser(some, sales, data)">Bill me
</button>
<b>WARNING: PRESS ONLY ONCE, DO NOT PRESS AGAIN!!</b>

Okay, this isn’t an actual solution; let’s move on to more serious proposals.

Solution 2 – using a global flag

The solution most people would probably think of first is using some global variable to record whether the user has already clicked on the button. You define a flag named something like clicked, initialized with false. When the user clicks on the button, if clicked is false, you change it to true and execute the function; otherwise, you do nothing at all. This can be seen in the following code:

let clicked = false;
.
.
.
function billTheUser(some, sales, data) {
  if (!clicked) {
    clicked = true;
    window.alert("Billing the user...");
    // actually bill the user
  }
}

This works, but it has several problems that must be addressed:

  • You are using a global variable, and you could change its value by accident. Global variables aren’t a good idea, in JavaScript or other languages. You must also remember to re-initialize it to false when the user starts buying again. If you don’t, the user won’t be able to make a second purchase because paying will become impossible.
  • You will have difficulties testing this code because it depends on external things (that is, the clicked variable).

So, this isn’t a very good solution. Let’s keep thinking!

Solution 3 – removing the handler

We may go for a lateral kind of solution, and instead of having the function avoid repeated clicks, we might just remove the possibility of clicking altogether. The following code does just that; the first thing that billTheUser() does is remove the onclick handler from the button, so no further calls will be possible:

function billTheUser(some, sales, data) {
  document
    .getElementById("billButton")
    .onclick = null;
  window.alert("Billing the user...");
  // actually bill the user
}

This solution also has some problems:

  • The code is tightly coupled to the button, so you won’t be able to reuse it elsewhere
  • You must remember to reset the handler; otherwise, the user won’t be able to make a second purchase
  • Testing will also be more complex because you’ll have to provide some DOM elements

We can enhance this solution a bit and avoid coupling the function to the button by providing the latter’s ID as an extra argument in the call. (This idea can also be applied to some of the further solutions that we’ll see.) The HTML part would be as follows; note the extra argument to billTheUser():

<button
  id="billButton"
  onclick="billTheUser('billButton', some, sales, data)"
>Bill me
</button>

We also have to change the called function so that it will use the received buttonId value to access the corresponding button:

function billTheUser(buttonId, some, sales, data) {
  document.getElementById(buttonId).onclick = null;
  window.alert("Billing the user...");
  // actually bill the user
}

This solution is somewhat better. But, in essence, we are still using a global element – not a variable, but the onclick value. So, despite the enhancement, this isn’t a very good solution either. Let’s move on.

Solution 4 – changing the handler

A variant to the previous solution would be not to remove the click function, but to assign a new one instead. We are using functions as first-class objects here when we assign the alreadyBilled() function to the click event. The function warning the user that they have already clicked could look something like this:

function alreadyBilled() {
  window.alert("Your billing process is running; don't
    click, please.");
}

Our billTheUser() function would then be like the following code – note how instead of assigning null to the onclick handler as in the previous section, now, the alreadyBilled() function is assigned:

function billTheUser(some, sales, data) {
  document
    .getElementById("billButton")
    .onclick = alreadyBilled;
  window.alert("Billing the user...");
  // actually bill the user
}

There’s a good point to this solution; if the user clicks a second time, they’ll get a warning not to do that, but they won’t be billed again. (From the point of view of user experience, it’s better.) However, this solution still has the very same objections as the previous one (code coupled to the button, needing to reset the handler, and harder testing), so we don’t consider it quite good anyway.

Solution 5 – disabling the button

A similar idea here is instead of removing the event handler, we can disable the button so the user won’t be able to click. You might have a function such as the one shown in the following code, which does exactly that by setting the disabled attribute of the button:

function billTheUser(some, sales, data) {
  document
    .getElementById("billButton")
    .setAttribute("disabled", "true");
  window.alert("Billing the user...");
  // actually bill the user
}

This also works, but we still have objections as with the previous solutions (coupling the code to the button, needing to re-enable the button, and harder testing), so we don’t like this solution either.

Solution 6 – redefining the handler

Another idea: instead of changing anything in the button, let’s have the event handler change itself. The trick is in the second line of the following code; by assigning a new value to the billTheUser variable, we are dynamically changing what the function does! The first time you call the function, it will do its thing, but it will also change itself out of existence by giving its name to a new function:

function billTheUser(some, sales, data) {
  billTheUser = function() {};
  window.alert("Billing the user...");
  // actually bill the user
}

There’s a special trick in the solution. Functions are global, so the billTheUser=... line changes the function’s inner workings. From that point on, billTheUser will be the new (null) function. This solution is still hard to test. Even worse, how would you restore the functionality of billTheUser, setting it back to its original objective?

Solution 7 – using a local flag

We can go back to the idea of using a flag, but instead of making it global (which was our main objection to the second solution), we can use an Immediately Invoked Function Expression (IIFE), which we’ll see more about in Chapter 3, Starting Out with Functions, and Chapter 11, Implementing Design Patterns. With this, we can use a closure, so clicked will be local to the function and not visible anywhere else:

var billTheUser = (clicked => {
  return (some, sales, data) => {
    if (!clicked) {
      clicked = true;
      window.alert("Billing the user...");
      // actually bill the user
    }
  };
})(false);

This solution is along the lines of the global variable solution, but using a private, local variable is an enhancement. (Note how clicked gets its initial value from the call at the end.) The only drawback we could find is that we'll have to rework every function that needs to be called only once to work in this fashion (and, as we’ll see in the following section, our FP solution is similar to it in some ways). Okay, it’s not too hard to do, but don’t forget the Don’t Repeat Yourself (DRY), usual advice!

We have now gone through multiple ways of solving our “do something only once” problem – but as we’ve seen, they were not very good! Let’s think about the problem functionally so that we get a more general solution.

A functional solution to our problem

Let’s try to be more general; after all, requiring that some function or other be executed only once isn’t that outlandish, and may be required elsewhere! Let’s lay down some principles:

  • The original function (the one that may be called only once) should do whatever it is expected to do and nothing else
  • We don’t want to modify the original function in any way
  • We need a new function that will call the original one only once
  • We want a general solution that we can apply to any number of original functions

A SOLID base

The first principle listed previously is the single responsibility principle (the S in the SOLID acronym), which states that every function should be responsible for a single functionality. For more on SOLID, check the article by Uncle Bob (Robert C. Martin, who wrote the five principles) at butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod.

Can we do it? Yes, and we’ll write a higher-order function, which we’ll be able to apply to any function, to produce a new function that will work only once. Let’s see how! We will introduce higher-order functions in Chapter 6, Producing Functions. There, we’ll go about testing our functional solution, as well as making some enhancements to it.

A higher-order solution

If we don’t want to modify the original function, we can create a higher-order function, which we’ll (inspiredly!) name once(). This function will receive a function as a parameter and return a new function, which will work only once. (As we mentioned previously, we’ll be seeing more of higher-order functions later; in particular, see the Doing things once, revisited section of Chapter 6, Producing Functions).

Many solutions

Underscore and Lodash already have a similar function, invoked as _.once(). Ramda also provides R.once(), and most FP libraries include similar functionality, so you wouldn’t have to program it on your own.

Our once() function may seem imposing at first, but as you get accustomed to working in an FP fashion, you’ll get used to this sort of code and find it to be quite understable:

// once.ts
const once = <FNType extends (...args: any[]) => any>(
  fn: FNType
) => {
  let done = false;
  return ((...args: Parameters<FNType>) => {
    if (!done) {
      done = true;
      return fn(...args);
    }
  }) as FNType;
};

Let’s go over some of the finer points of this function:

  • Our once() function receives a function (fn) as its parameter and returns a new function, of the same type. (We’ll discuss this typing in more detail shortly.)
  • We define an internal, private done variable, by taking advantage of closure, as in Solution 7. We opted not to call it clicked (as we did previously) because you don’t necessarily need to click on a button to call the function; we went for a more general term. Each time you apply once() to some function, a new, distinct done variable will be created and will be accessible only from the returned function.
  • The return statement shows that once() will return a function, with the same type of parameters as the original fn() one. We are using the spread syntax we saw in Chapter 1, Becoming Functional. With older versions of JavaScript, you’d have to work with the arguments object; see developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/arguments for more on that. The modern way is simpler and shorter!
  • We assign done = true before calling fn(), just in case that function throws an exception. Of course, if you don’t want to disable the function unless it has successfully ended, you could move the assignment below the fn() call. (See Question 2.4 in the Questions section for another take on this.)
  • After the setting is done, we finally call the original function. Note the use of the spread operator to pass along whatever parameters the original fn() had.

Typing for once() may be obscure. We have to specify that the type of the input function and the type of once() are the same, and that’s the reason for defining FNType. Figure 2.2 shows that TypeScript correctly understands this (Check the answer to Question 1.7 at the end of this book for another example of this):

Figure 2.2 – Hovering shows that the type of once()’s output matches the type of its input

Figure 2.2 – Hovering shows that the type of once()’s output matches the type of its input

If you’re not still used to TypeScript, let’s see the pure JavaScript equivalent, which is the same code but for typing:

// once_JS.js
const once = (fn) => {
  let done = false;
  return (...args) => {
    if (!done) {
      done = true;
      return fn(...args);
    }
  };
};

So, how would we use it? We first create a new version of the billing function.

const billOnce = once(billTheUser);

Then, we rewrite the onclick method as follows:

<button id="billButton"
  onclick="billOnce(some, sales, data)">Bill me
</button>;

When the user clicks on the button, the function that gets called with the (some, sales, data) argument isn’t the original billTheUser() but rather the result of having applied once() to it. The result of that is a function that can be called only a single time.

You can’t always get what you want!

Note that our once() function uses functions such as first-class objects, arrow functions, closures, and the spread operator. Back in Chapter 1, Becoming Functional, we said we’d be needing those, so we’re keeping our word! All we are missing from that chapter is recursion, but as the Rolling Stones sang, You Can’t Always Get What You Want!

We now have a functional way of getting a function to do its thing only once, but how would we test it? Let’s get into that topic now.

Testing the solution manually

We can run a simple test. Let’s write a squeak() function that will, appropriately, squeak when called! The code is simple:

// once.manual.ts
const squeak = a => console.log(a, " squeak!!");
squeak("original"); // "original squeak!!"
squeak("original"); // "original squeak!!"
squeak("original"); // "original squeak!!"

If we apply once() to it, we get a new function that will squeak only once. See the highlighted line in the following code:

// continued...
const squeakOnce = once(squeak);
squeakOnce("only once"); // "only once squeak!!" squeakOnce("only once"); // no output
squeakOnce("only once"); // no output

The previous steps showed us how we could test our once() function by hand, but our method is not exactly ideal. In the next section, we’ll see why and how to do better.

Testing the solution automatically

Running tests by hand isn’t suitable: it gets tiresome and boring, and it leads, after a while, to not running the tests any longer. Let’s do better and write some automatic tests with Jest:

// once.test.ts
import once } from "./once";
describe("once", () => {
  it("without 'once', a function always runs", () => {
    const myFn = jest.fn();
    myFn();
    myFn();
    myFn();
    expect(myFn).toHaveBeenCalledTimes(3);
  });
  it("with 'once', a function runs one time", () => {
    const myFn = jest.fn();
    const onceFn = jest.fn(once(myFn));
    onceFn();
    onceFn();
    onceFn();
    expect(onceFn).toHaveBeenCalledTimes(3);
    expect(myFn).toHaveBeenCalledTimes(1);
  });
});

There are several points to note here:

  • To spy on a function (for instance, to count how many times it was called), we need to pass it as an argument to jest.fn(); we can apply tests to the result, which works exactly like the original function, but can be spied on.
  • When you spy on a function, Jest intercepts your calls and registers that the function was called, with which arguments, and how many times it was called.
  • The first test only checks that if we call the function several times, it gets called that number of times. This is trivial, but we’d be doing something wrong if that didn’t happen!
  • In the second test, we apply once() to a (dummy) myFn() function, and we call the result (onceFn()) several times. We then check that myFn() was called only once, though onceFn() was called three times.

We can see the results in Figure 2.3:

Figure 2.3 – Running automatic tests on our function with Jest

Figure 2.3 – Running automatic tests on our function with Jest

With that, we have seen not only how to test our functional solution by hand but also in an automatic way, so we are done with testing. Let’s just finish by considering an even better solution, also achieved in a functional way.

Producing an even better solution

In one of the previous solutions, we mentioned that it would be a good idea to do something every time after the first click, and not silently ignore the user’s clicks. We’ll write a new higher-order function that takes a second parameter – a function to be called every time from the second call onward. Our new function will be called onceAndAfter() and can be written as follows:

// onceAndAfter.ts
const onceAndAfter = <
  FNType extends (...args: any[]) => any
>(
  f: FNType,
  g: FNType
) => {
  let done = false;
  return ((...args: Parameters<FNType>) => {
    if (!done) {
      done = true;
      return f(...args);
    } else {
      return g(...args);
    }
  }) as FNType;
};

We have ventured further into higher-order functions; onceAndAfter() takes two functions as parameters and produces a third one, which includes the other two within.

Function as default

You could make onceAndAfter() more powerful by giving a default value for g, such as () => {}, so if you didn’t specify the second function, it would still work fine because the default do-nothing function would be called instead of causing an error.

We can do a quick-and-dirty test along the same lines as we did earlier. Let’s add a creak() creaking function to our previous squeak() one and check out what happens if we apply onceAndAfter() to them. We can then get a makeSound() function that should squeak once and creak afterward:

// onceAndAfter.manual.ts
import { onceAndAfter } from "./onceAndAfter";
const squeak = (x: string) => console.log(x, "squeak!!");
const creak = (x: string) => console.log(x, "creak!!");
const makeSound = onceAndAfter(squeak, creak);
makeSound("door"); // "door squeak!!"
makeSound("door"); // "door creak!!"
makeSound("door"); // "door creak!!"
makeSound("door"); // "door creak!!"

Writing a test for this new function isn’t hard, only a bit longer. We have to check which function was called and how many times:

// onceAndAfter.test.ts
import { onceAndAfter } from "./onceAndAfter";
describe("onceAndAfter", () => {
  it("calls the 1st function once & the 2nd after", () => {
    const func1 = jest.fn();
    const func2 = jest.fn();
    const testFn = jest.fn(onceAndAfter(func1, func2));
    testFn();
    testFn();
    testFn();
    testFn();
    expect(testFn).toHaveBeenCalledTimes(4);
    expect(func1).toHaveBeenCalledTimes(1);
    expect(func2).toHaveBeenCalledTimes(3);
  });
});

Notice that we always check that func1() is called only once. Similarly, we check func2(); the count of calls starts at zero (the time that func1() is called), and from then on, it goes up by one on each call.

Summary

In this chapter, we’ve seen a common, simple problem based on a real-life situation. After analyzing several typical ways of solving that, we went for a functional thinking solution. We saw how to apply FP to our problem and found a more general higher-order solution that we could apply to similar problems with no further code changes. We saw how to write unit tests for our code to round out the development job.

Finally, we produced an even better solution (from the point of view of the user experience) and saw how to code it and how to unit-test it. Now, you’ve started to get a grip on how to solve a problem functionally; next, in Chapter 3, Starting Out with Functions, we’ll delve more deeply into functions, which are at the core of all FP.

Questions

2.1 No extra variables: Our functional implementation required using an extra variable, done, to mark whether the function had already been called. Not that it matters, but could you make do without using any extra variables? Note that we aren’t telling you not to use any variables, it’s just a matter of not adding any new ones, such as done, and only as an exercise!

2.2 Alternating functions: In the spirit of our onceAndAfter() function, can you write an alternator() higher-order function that gets two functions as arguments and, on each call, alternatively calls one and another? The expected behavior should be as in the following example:

const sayA = () => console.log("A");
const sayB = () => console.log("B");
const alt = alternator(sayA, sayB);
alt(); // A
alt(); // B
alt(); // A
alt(); // B
alt(); // A
alt(); // B

2.3 Everything has a limit! As an extension of once(), could you write a higher-order function, thisManyTimes(fn,n), that would let you call the fn() function up to n times, but would do nothing afterward? To give an example, once(fn) and thisManyTimes(fn,1) would produce functions that behave the same way. Do also write tests for it.

2.4 Allow for crashing: Suppose we apply once() to a function, and the first time that function gets called, it crashes. Here, we may want to allow a second call to the function, hoping it wouldn’t crash again. We want an onceIfSuccess() function, that will get a function as a parameter and produce a new function that will run successfully only once, but will be allowed to fail (throwing exceptions) many times if need be. Implement onceIfSuccess(), and don’t forget to write unit tests for it.

2.5 Say no to arrows: Implement once() using classic functions, instead of arrow functions. This is just meant to help you explore the slightly different needed data typing syntax.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Apply functional programming concepts and techniques to everyday JavaScript or TypeScript programming
  • Master functional programming in JavaScript and TypeScript to solve real-world development problems
  • Apply functional programming to get better testable programs with higher modularity and reusability

Description

Functional programming is a programming paradigm that uses functions for developing software. This book is filled with examples that enable you to leverage the latest JavaScript and TypeScript versions to produce modern and clean code, as well as teach you to how apply functional programming techniques to develop more efficient algorithms, write more concise code, and simplify unit testing. This book provides comprehensive coverage of the major topics in functional programming to produce shorter, clearer, and testable programs. You’ll begin by getting to grips with writing and testing pure functions, reducing side effects, as well as other key features to make your applications functional in nature. The book specifically explores techniques to simplify coding, apply recursion, perform high-level coding, learn ways to achieve immutability, implement design patterns, and work with data types. By the end of this book, you’ll have developed the practical programming skills needed to confidently enhance your applications by adding functional programming to wherever it’s most suitable.

Who is this book for?

If you are a JavaScript or TypeScript developer looking to enhance your programming skills, then this book is for you. The book applies to both frontend developers working with frameworks such as React, Vue, or Angular as well as backend developers using Node.js or Deno.

What you will learn

  • Understand when to use functional programming versus classic object-oriented programming
  • Use declarative coding instead of imperative coding for clearer, more understandable code
  • Know how to avoid side effects and create more reliable code with closures and immutable data
  • Use recursion to help design and implement more understandable solutions to complex problems
  • Define functional programing data types with or without TypeScript, add type checking, and implement immutability
  • Apply advanced containers to get better structures to tackle errors and implement async programming
Estimated delivery fee Deliver to Portugal

Premium delivery 7 - 10 business days

€17.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Apr 28, 2023
Length: 614 pages
Edition : 3rd
Language : English
ISBN-13 : 9781804610138
Category :
Languages :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning
Estimated delivery fee Deliver to Portugal

Premium delivery 7 - 10 business days

€17.95
(Includes tracking information)

Product Details

Publication date : Apr 28, 2023
Length: 614 pages
Edition : 3rd
Language : English
ISBN-13 : 9781804610138
Category :
Languages :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 109.97
React 18 Design Patterns and Best Practices
€33.99
The Ultimate Docker Container Book
€37.99
Mastering JavaScript Functional Programming
€37.99
Total 109.97 Stars icon

Table of Contents

16 Chapters
Chapter 1: Becoming Functional – Several Questions Chevron down icon Chevron up icon
Chapter 2: Thinking Functionally – A First Example Chevron down icon Chevron up icon
Chapter 3: Starting Out with Functions – A Core Concept Chevron down icon Chevron up icon
Chapter 4: Behaving Properly – Pure Functions Chevron down icon Chevron up icon
Chapter 5: Programming Declaratively – A Better Style Chevron down icon Chevron up icon
Chapter 6: Producing Functions – Higher-Order Functions Chevron down icon Chevron up icon
Chapter 7: Transforming Functions – Currying and Partial Application Chevron down icon Chevron up icon
Chapter 8: Connecting Functions – Pipelining, Composition, and More Chevron down icon Chevron up icon
Chapter 9: Designing Functions – Recursion Chevron down icon Chevron up icon
Chapter 10: Ensuring Purity – Immutability Chevron down icon Chevron up icon
Chapter 11: Implementing Design Patterns – The Functional Way Chevron down icon Chevron up icon
Chapter 12: Building Better Containers – Functional Data Types Chevron down icon Chevron up icon
Answers to Questions Chevron down icon Chevron up icon
Bibliography Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.6
(14 Ratings)
5 star 78.6%
4 star 7.1%
3 star 14.3%
2 star 0%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by




José Juan Ojeda Feb 19, 2024
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Feefo Verified review Feefo
CD May 15, 2023
Full star icon Full star icon Full star icon Full star icon Full star icon 5
After reading Mastering JavaScript Functional Programming by Federico Kereki, I came away with a much deeper knowledge of functional JavaScript than I had previously.Admittedly, I had a cursory knowledge of functional techniques in JavaScript and have read other texts on the subject, so I was not truly comfortable using them in a professional setting.Kereki's examples are not only clear and easy-to-understand, but he also provides numerous approaches one could take before showing the best example. This is really helpful, because code is so subjective and often is easy to settle on one approach, thinking it is the best one until you see an even better one in the next paragraph! I love seeing this as it feels like you've unlocked something new and you can easily compare the best version to the other versions to see exactly why it is better.Another aspect I like about this book is that it puts a strong emphasis on testing the examples provided using Jest. This is very practical since Jest is a leading testing tool in the JavaScript world and will give one valuable experience if they have never dealt with testing frameworks before. In addition, there are many examples showing how to test pure and impure functions and how to deal with the differences.Besides being a strong test on functional approaches in JavaScript, the author sprinkles in some nice history behind JavaScript and other programming languages that provide a nice backstory to how we got here today. This makes the book both informative and fun to read.Declarative programming has been a hot topic for several years in the JavaScript world (mostly due to React) and this book covers it in great detail with very practical examples. I really appreciate that as the term is thrown around a fair bit by people, but rarely specified as clearly.There is a lot to cover in writing good, clean functional code and I think that Mastering JavaScript Functional Programming provides something for everyone at every level. The examples in this book should serve one for several years as it takes time to fully absorb and apply these concepts to real-world scenarios.I commend Federico Kereki for a terrific 3rd edition and look forward to reading more of his work in the future.
Amazon Verified review Amazon
matthew eldredge May 15, 2023
Full star icon Full star icon Full star icon Full star icon Full star icon 5
"Mastering JavaScript Functional Programming" is an exceptional book that provides a comprehensive guide to mastering functional programming in JavaScript. As an experienced JavaScript developer, I found this book to be an invaluable resource for advancing my skills and understanding of functional programming concepts.The author's approach to explaining complex concepts is clear, concise, and beginner-friendly. Each chapter builds upon the previous one, gradually introducing advanced topics and demonstrating practical examples along the way. The book strikes a perfect balance between theory and hands-on exercises, making it easy to grasp the core concepts of functional programming and apply them to real-world scenarios.One of the highlights of this book is its focus on writing clean, robust, and maintainable code. The author emphasizes the importance of immutability, pure functions, and higher-order functions, guiding readers toward writing easier code to reason about, test, and debug. The code examples provided are well-explained and illustrate best practices for structuring functional JavaScript code.Additionally, the book covers a wide range of functional programming techniques, including currying, composition, recursion, and monads. These topics are explained in a practical and approachable manner, allowing readers to gain a deep understanding of their applications and benefits.The book is excellently structured, with each chapter building upon the previous one seamlessly. The writing style is engaging, and the content is presented in a logical and organized manner, making it easy to follow and digest.In conclusion, "Mastering JavaScript Functional Programming" is a must-read for JavaScript developers who want to unlock the power of functional programming. Whether you are a beginner or an experienced developer, this book will undoubtedly enhance your understanding of functional programming concepts and help you write cleaner, more maintainable code. I highly recommend it to anyone seeking to level up their JavaScript skills and embrace functional programming paradigms.
Amazon Verified review Amazon
Peter J. Jonas May 05, 2023
Full star icon Full star icon Full star icon Full star icon Full star icon 5
A fascinating, well-written book. Although you need to experience in programming to follow, it starts at the beginning and builds up, giving you all the knowledge you need to understand and then master functional programming. Easy to read, like an enchanting fiction book.This book uses TypeScript a lot, so if you have no experience with that, it can be challenging to understand everything. Still, this is an excellent (I rate it five stars despite that) book on this topic, worth its price; just be aware of it and think through it before buying it.Then buy it. You have to know TypeScript anyway.
Amazon Verified review Amazon
Majdm May 17, 2023
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This book has been truly helpful for me. The author's knowledge and passion were really good. This book made complex ideas easy to understand like immutability and lazy evaluation, giving me the confidence to embrace functional programming. The practical examples and code snippets helped my understanding and changed the way I code. If you want to move to more senior level in your JavaScript programming or learn more in depth about javascript, this book is a must-read.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela