Well it’s probably no surprise that I’m all for it. To your concerns, I think I have a solid counter-point for each one:
- It’s the same API, just remember that it’s curried, data-last, and immutable. That’s why there aren’t separate API docs for it.
- We’ve been using the full build this entire time anyway, so whether we use it or not we were putting it in the bundle. If we decide to use the babel plugin or do modular importing, then it’s no larger than importing the non-immutable method. So either way, there’s no difference.
- I haven’t seen any performance benchmarks on this, it’s sort of bike shedding.
JavaScript is great for functional programming because it has first class functions, and object oriented code is “sort of awkward” as the Mostly Adequate Guide puts it (link below). The problem is that currently its standard library is missing core functionality such as currying and immutability. Lodash FP (among others, such as ramda) solves that problem. By not allowing the use of this library, we’d be essentially saying functional programming is not allowed at ShakaCode. Considering our awesome embrace of new tech and methods, I find it hard to believe that we truly would want to have this as a policy.
Perhaps those interested in the topic could read The Mostly Adequate Guide to Functional Programming. I’ve already been able to make drastic simplifications to my code by embracing some of the basics I read about here.
Here is a simple example using the FP remove:
const myArray = [4, 3, 1, 6, 2, 5];
const sortedEvens = flow(remove(n => n % 2 === 0), sortBy);
const result = sortedEvens(myArray); // [2, 4, 6]
What if, in this case, myArray
was actually taken from a React component’s state
, meaning I had to be careful not to mutate it? You’d be fine with the above. The alternative when using the non-FP would be:
const myArray = [4, 3, 1, 6, 2, 5];
const myArrayClone = clone(myArray);
const evens = remove(myArrayClone, n => n % 2 === 0);
const result = sortBy(myArrayClone); // [2, 4, 6]
While the difference is only one line, you are actually importing another lodash method (so FP would actually be less size in this case), you are still having to perform a clone (so no performance gain), and I’m actually using fewer methods while, in my opinion, expressing my intent in a much clearer way (you expressed concern about the mental compilation required of developers).
And it’s this last point that is really the whole reason I’m doing it: I’m declaring what I want to have happen, sortAndJoin
, instead of telling it how to do each step myself (declarative versus imperative coding).
Declarative, as opposed to imperative, means that we will write expressions, as opposed to step by step instructions.
Think of SQL. There is no “first do this, then do that”. There is one expression that specifies what we’d like from the database. We don’t decide how to do the work, it does. When the database is upgraded and the SQL engine optimized, we don’t have to change our query. This is because there are many ways to interpret our specification and achieve the same result.
(Mostly Adequate Guide to Functional Programming, Ch. 6)