Functional Programming Features in JavaScript

John Au-Yeung - Jan 25 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

JavaScript is an easy to learn programming language. It also uses lots of functional programming features that make our lives easier.

In this article, we’ll take a look at some functional programming features of JavaScript that we can use in our code.

What is Functional Programming?

Functional programming is a programming paradigm where we treat computations as an evaluation of mathematical functions. This means we avoid changing state and mutating data,

It’s a declarative programming paradigm where we only tell how the program should run in a high level to create our program rather than writing instructions to tell the computer how to run a program step by step.

Functional programming emphasizes the use of pure functions, where a function’s arguments determine its output.

Also, side effects should be eliminated in functions since they make a function impure.

Eliminating side effects also make functions easier to test since we only have to put in inputs and check its output rather than also having to check what the side effects have done.

Lazy Evaluation

Lazy evaluation is evaluating values only when the value is needed. In JavaScript, we can do that by returning a value in a function and then invoking the function when needed.

For instance, we can write the following code to do that:

const lazy = () => 2 + 1
Enter fullscreen mode Exit fullscreen mode

In the code above, we put our value 3 as the return value of the lazy function.

Now we only get the value when we need it by calling the lazy function.

This is opposed to setting 3 as a variable as we do below:

let val = 2 + 1;
Enter fullscreen mode Exit fullscreen mode

The code above is evaluated immediately rather than waiting for the lazy function to be evaluated before returning the value.

Lazy evaluations avoid repeated evaluation, which makes our code more efficient than evaluating expressions immediately.

We can also implement lazy evaluation with functions by return the function instead of assigning a function directly to a variable.

For instance, we can write the following to create a lazily evaluated function as follows:

const lazyAdd = (a, b) => () => a + b;
const add = lazyAdd(1, 2);
const result = add();
Enter fullscreen mode Exit fullscreen mode

In the code above, we have the lazyAdd function, which returns a function that returns the 2 parameters added together.

Then when we call the lazyAdd function with 2 numbers, we return a function that’ll return the 2 numbers added together instead of returning the evaluated expression directly.

Then when we call add , we actually return 1 and 2 added together.

This again delays the evaluation of the sum until it’s needed. And it’s opposed to the following code:

const add = (a, b) => a + b;
const result = add(1, 2);
Enter fullscreen mode Exit fullscreen mode

which evaluates the 2 arguments added together immediately.

Monoid

In functional programming, a monoid is a set of elements that has 3 special properties when combined with an operation named concat .

Monoids have the following characteristics:

  • The operation must combine 2 values into the 3rd value of the same set. If a and b are part of the set, then concat(a, b) should also be part of the same set.
  • The operation must be associative. That is, concat(a, concat(b, c)) should be the same as concat(concat(a, b), c) .
  • The set must have a neutral element regarding its operation. If the neutral element is combined with any other value, it shouldn’t change it. That is, concat(a, neutral) === concat(neutral, a) .

There’re many examples of monoids in JavaScript. The most common are strings and numbers.

For instance, with numbers, we can check that they meet the 3 properties above.

Given that a is 1 and b is 2, and the concat operator is + , we can check that the first property is met by writing:

a + b === 3
Enter fullscreen mode Exit fullscreen mode

a and b are both numbers and 3 is a number, so they’re in the same set, and the first criterion is met.

Then we can check associativity as follows:

((a + b) + 3) === (a + (b + 3))
Enter fullscreen mode Exit fullscreen mode

Since that returns true , we can group them in the order we want, so + with numbers is associative.

We can check if a set has a neutral element by picking 0 as the neutral element.

For instance:

a + 0 === 0 + a
Enter fullscreen mode Exit fullscreen mode

returns true , so we know that the set of numbers has a neutral element, which is 0. Therefore, we know that there’s a neutral element when adding numbers.

Therefore, the addition operation with numbers is a monoid.

Monoids are useful because it lets us compose multiple simple operations to create complex behavior out of them, without having to introduce new concepts in our code.

They always return the elements in the same set, so we can continue composing these elements and operations together.

Associativity lets us disregard the order of the compose and still get the same result, reducing the cognitive load that we need when we need to compose multiple operations.

Conclusion

JavaScript exhibits some functional programming characteristics. This makes writing code more like defining and using mathematical functions.

For instance, things can be lazily evaluated to increase efficiency and it has monoids like number addition. Monoids are useful because of the easy composition of multiple operations.

Functional programming emphasizes pure functions, which are easier to test.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .