Functional programming is an awesome thing. There are many functional languages out of the space, so if you want to cultivate your knowledge in an artistic level, you can turn to a significant number of them including Haskell, OCaml, F#, ML, Clojure, Erlang, Lisp, and many more. However, in this series, I will teach you the fundamentals of functional programming in JavaScript. As of this writing, JavaScript means rather ES 2015 (in its maiden name, ES6, or EcmaScript 6) than the good old ES5 — thus I will incorporate ES 2015 features into the samples and explanations whenever I can.

Why Be Functional?

The proper use of functional programming features makes you code shorter, more expressible, and less buggy than the traditional imperative style. I cannot force you to believe this bold statement but, hopefully, you will understand it while we take this journey together.

Take a look at this short JavaScript sample (Example-01-01):

We have an array, dives, which contains scuba dive log records with dive site names and depth values (given in feet). The imperative style we apply uses a for-loop to extract those dive log entries into deepDives where the depth was greater than or equal 90 feet.

With the help of the filter higher order function, we can eliminate the for-loop and describe the same task in a clearer way (Example-01-02):

We passed a function to filter to determine whether a specific item in the array should be included in the filtered result:

With the help of functional programming tools, we split the imperative approach of Example-01-01 into two functions. First, filter described the for-loop logic that iterates through the elements of the array and using a predicate to decide whether it needs to include the particular item in the result. Second, the anonymous function passed to filter declared the predicate.

If we did not have the filter function in the standard JavaScript library, we could implement it, and use the functional approach (Example-01-03):

Divide and Conquer

Splitting an imperative task into smaller parts and applying the functional approach makes program maintenance and modification easier and shorter. Let’s assume that we need to modify our original example so that we can extract the shallow dives, too. If the shallow dive requirement came later — long after we already implemented the selection of deep dives — we might repeat the same for-loop pattern for creating a shallowDives array as we used earlier for deepDives (Example-01-04):

Here, not only the double application of the for-loop is redundant, but also the second predicate function we used to create shallowDives. If a dive is not deep, it is shallow, and vice versa. With the functional approach, we do not need to declare two distinct predicates (Example-01-05):

In contrast to filter, reject uses a predicate to decide which items to exclude from the input array. Thus, dives.reject(isDeep) returns those dive log entries that are not considered deep dives.

We have just barely scratched the surface of Functional JavaScript programming. In the next part, we discuss why we call filter, reject, and their companions higher order functions.

Leave a comment

Your email address will not be published. Required fields are marked *