Easy to use when you have two numbers, right? But what if you want to have a bunch of numbers that you add a single number to? You could:
But that's ugly and awfully imperative. Instead, we can use a built in method on arrays called `map(..)`:
But we can do better than that. Let's pull out that function expression:
Notice how I only pass a reference to `add42`, but I don't call it like `add42()`. That's super important. `map(..)` will call `add42(..)` for us.
But, instead of defining that function manually, we could use another FP technique, closure, to make a utility that produces a composition on top of `sum(..)`:
The `makeAdder(..)` function makes and returns a new function. The new function that's returned is what we assign to the variable `add42`. That function has a closure over the variable `y`, which we pass in as `42`. It's then called by `map(..)` once for each value in the list, which will be the `x` parameter. Now that we have an `x` and a `y`, the `sum(x,y)` call computes the new value for each item in the list.
For our last trick, let's say we wanted to first add that `42` to all numbers in our list, and then sum all the numbers to get one big number. We can use another array method `reduce(..)` for that. `reduce(..)` takes a function similar to `map(..)`, but *that* function needs two values. The first parameter is the running total, and the second parameter is the current value in the list. In other words, it might be used like this:
Also, look at that `0` as the second argument to `reduce(..)`. That's the initial value to start the reduction with. But does that function signature look familiar? It's exactly the same as the `sum(..)` we already defined. So we could just call `reduce( sum, 0 )`. Next, we'll observe that since `map(..)` is returning a new array, we can *chain* the `reduce(..)` call directly off the `map(..)` call. Putting all this together, we have:
Processing values in lists is a lot more fun when we learn tools like `map(..)` and `reduce(..)`, and function closure. Happy coding!
my detour to Clojure(Script) (Elm would have been another option).
Yeah, JS is not actually a FP language. But I do think you can *think functionally* in parts of your program, which helps improve things, even if you don't have an entirely pure FP approach to all the code.
I taught a 3hr Frontend Masters course called "Functional-Lite Programming" which tries to sift through the bits of FP theory/concept that we can easily apply to JS without getting into all the terminology and dogma. I encourage devs to explore this more fully, as I've found that it really helps to be 50% FP than 0% -- 100% is not necessary to improve code.