- What is data mutation? What should I keep in mind about it?
- What do the functions map, filter, and reduce do, when would be a good example of when to use them? Does this mutate my data?
Functional Programming (FP) is a programming paradigm that's different from object-oriented programming. Functional programming is all about separating data from behavior so that software is more predictable, more robust, and easier to test. Certain tools become readily available with functional programming because functions can be used as data, which means they can be passed around as parameters and used as inputs into other functions. This can make the code more concise and easier to read.
Which companies use Functional Programming?
- Bloomberg uses Ocaml which is a functional programming language
- Bloomberg utilizes functional programming (OCaml) in production for powering part of its Bloomberg Professional Services product. Aided by a collaboration with LexiFi, several Bloomberg applications are now making use of GUI generation and financial contract representation; Bloomberg furthermore has embraced OCaml to develop domain specific languages and the problem of integrating the vast amount of data available in the Bloomberg infrastructure.(cufp.org)
- Walmart uses Clojure, a dialect of the Lisp programming language. Walmart runs Clojure at scale.
- How did Walmart's eReceipts team of 8 developers build a system to process and integrate every purchase at Walmart's 5000+ stores, including online and mobile data? Simple - they used Clojure "all the way down" to build a powerful data system enabling the popular Savings Catcher, Vudu Instawatch, Black Friday's 1-Hour Guarantee, and other programs to improve the customer experience and streamline operations.(cognitect.com)
Participants will be able to learn the basics of functional programming in JavaScript.
- map
- filter
- reduce
- mutation
- What is Functional Programming (11 mins read)
- Map, Filter, and Reduce in JavaScript (6 mins read)
- 4 10-min Videos: Fun Fun Functional Programming (watch all 4 parts)
Here is a list of tools that become available with functional programming. These functions are commonly used on containers, such as an array, to apply another function across all elements in that container.
The purpose of map
is to process every element of an array in the exact same way. When you call map
on an array, it executes that callback on every element within it, returning a new array with all of the values that the callback returned.
Example: an array of integers, add '3' to every integer
const intArray = [1, 2, 3]
function add3(value) {
return value + 3;
}
const result = intArray.map(add3) // result is [4, 5, 6]
The purpose of the filter is to return a specified subset of the original array elements. When you call filter
on an array and a function, it uses the function to check to see if the elements in the array meet a certain condition. If it does meet the condition, it keeps it in the array; if it does not meet the condition, it filters it out of the array.
Example: Let's say that you have an array of restaurants, and you want to know what your options are for only restaurants that are open at 7 am. You have a class called Restaurant
, which has a property openingTime
.
const validRestaurants = allRestaurants.filter(restaurant => restaurant.openingTime <= 7)
The purpose of reduce
is to process elements of an array in a way that every element will be incorporated into the final solution. When you call reduce
on an array and a function, it applies the function to every element of the array, while keeping track of a previous value.
Example: You are going to binge-watch Season 2 of "Stranger Things", and you want to know how long it will take. You have a class called Episode
, which has duration
as the value, and you have all of the episodes of Stranger Things stored in an array.
const seasonTwoEpisodes = allEspisodes.filter((episode) => episode.season == 1)
function addDuration(episode1, episode2) {
return episode1.duration + episode2.duration;
}
const total = seasonTwoEpisodes.reduce(addDuration, 0)
Something you may have noticed is that when the new values were calculated from the original arrays, the old array values stayed unchanged. Therefore, they are considered to be "non-mutating". Let's look back at the example in Part I.
Example: an array of integers, add 3
to every integer
const intArray = [1, 2, 3]
function add3(value) {
return value + 3;
}
const result = intArray.map(add3) // result is [4, 5, 6]
If you inspect intArray
, the values are still: [1, 2, 3]. There are many functions that have mutating vs. non-mutating behavior. For example, splice
is a mutating way to replace values, as opposed to map
. A good article that explains different mutating vs. non-mutating functions can be found here
Generally, according to the functional programming paradigm, it's better to avoid mutation of data. This will help keep code behaving more robustly and predictably. In fact, some programming languages are specially crafted for, or influenced by Functional Programming, some examples of Functional Programming Languages are:
JavaScript is not a purely functional language, but has some methods like map
, reduce
, and filter
are functional in nature. Purely functional languages are specialized languages and have often have limited applications.
You may wonder why you would want to avoid mutation. Let's say we defined a method, add3(intArray)
, that would update an array of integers whenever we called it instead of returning a new array. We would say that such a method has a "side effect" of changing the array (intArray
). Now, what if we had to call add3
from two different parts of our application? We would have to start worrying about how many times add3(intArray)
was called because every time we call it, intArray
would change.
This might not be a problem in a small application, but as the application grows over time, we may get unexpected results. As more people start working on the project, they may not be aware that each time they call add3(intArray)
the intArray
would change. This could quickly break an application in weird and hard-to-debug ways. For that reason, developers tend to prefer avoiding side-effects. Using a method like map
, which returns a new array and leaves intArray
as it is, is an easy way to avoid these types of mistakes.