More Javascript Functional Programming Features

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 look at some functional programming features of JavaScript, including functors and pure functions.

Functor

A functor is something that can be mapped over. If an entity’s entries can be mapped to new values, then it’s a functor.

In JavaScript, anything that we can call the map method over is a functor. This would be an array in JavaScript.

For instance, with an array, we can call map as follows:

const arr = [1, 2, 3].map(a => a * 2);
Enter fullscreen mode Exit fullscreen mode

In the code above, we passed in a callback that returns an array with each value of the original array doubled. Therefore, an array is a functor.

In addition to arrays, we can create arrays by converting array-like iterable objects into arrays with the spread operator.

For instance, if we have a generator function:

const generator = function*() {
  yield 1;
  yield 2;
  yield 3;
}
Enter fullscreen mode Exit fullscreen mode

Then we can convert it to an array and call map on the converted array as follows:

const arr = [...generator()].map(a => a * 2);
Enter fullscreen mode Exit fullscreen mode

In the code above, we used the spread operator to convert the iterator returned by generator into an array.

Then we get the same result as the first example.

Other examples of array-like iterable object include the arguments object, DOM NodeLists, sets, maps, and the Files object.

For non-iterable array-like objects. That is, objects that have numerical keys and the length property, we can use Array.from to convert it to an array.

We can call Array.from as follows:

const obj = {
  0: 1,
  1: 2,
  2: 3,
  length: 3
}
const arr = Array.from(obj).map(a => a * 2);
Enter fullscreen mode Exit fullscreen mode

In the code above, we passed obj into Array.from to convert it to an array, then call map on it as we did in the previous examples.

Pure Functions

Pure functions are functions that always return the same output for a given set of inputs.

Also, they don’t produce any side effects. They’re useful because they’re easy to understand and test since they just manipulate inputs and return an output.

They also don’t commit any side effects so we don’t have things that happen outside the function itself that are caused by the function.

An example of a pure function includes:

const add = (x, y) => x + y;
Enter fullscreen mode Exit fullscreen mode

The add function just takes 2 numbers and return the result added together, so it’s a pure function. It doesn’t modify anything outside the function, so it commits no side effects.

An example of a function that’s not pure is something like:

let foo = 1;
const impureAdd = (a, b) => {
  foo = 3;
  return a + b;
};
Enter fullscreen mode Exit fullscreen mode

The impureAdd function commits a side effect by reassigning the foo variable, which is outside the function to a different value.

Therefore, impureAdd isn’t a pure function.

Side Effects

Side effects are any operation that’s observable outside the called function other than its returned value.

For instance, they include operations like:

  • changing values of variables outside a function
  • logging to the console
  • drawing on the screen
  • write file to disk
  • run external processes
  • calling other functions that commit side effects
  • … and anything else that does things outside the function

With functional programming, side effects are minimized so that a function is easier to read and test as we don’t have to check their side effect results.

Referential Transparency

Referential transparency is the fact that an expression may be replaced by its value or anything having the same value without changing the result of the program.

The function should always return the same value for a given argument without having any other effect.

Also, this means that our functions have no side effects.

For instance, the add function that we have above have referential transparency since we always get the same output for the same set of arguments passed in.

Conclusion

To make our code easy to read and test, we stick with pure functions as much as possible.

Side effects are avoided as possible so that we don’t have to deal with checking them.

Functors are anything that we can map their values over. In JavaScript, arrays have the map method, so JavaScript arrays are functors. We can also convert many kinds of objects to arrays, including iterable and non-iterable array-like objects.

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