Did you know that Lodash - the popular JavaScript utility library - had a functional flavor?

The most exciting part to me is that functions of Lodash FP do not mutate the data they receive.

As a Clojure developer, I am excited because I am addicted to data immutability.

Immutability

This article is an excerpt from my book about Data-Oriented Programming.

More excerpts are available on my blog.


TL;DR

Lodash FP differs from the standard Lodash on 4 main points:

  1. The functions receive the data to be manipulated as last argument
  2. The functions do not mutate the data they manipulate
  3. The functions are auto curried
  4. The functions receive the iteratee as first argument

Immutability

In Lodash FP, the functions do not mutate the data they manipulate.

For instance, the set() function differs from the standard Lodash in two points:

  1. It receives the object as last argument
  2. It returns a new version of the object instead of modifying the object

In the following code snippet, you see that a is not modified by fp.set():

var a = {foo: 1};
var b = fp.set("foo", 2, a);
[a, b]

However in standard Lodash, a is modified by _.set():

var a = {foo: 1};
var b = _.set(a, "foo", 2);
[a, b]

The implementation of the data immutability is based on structural sharing, which makes it efficient both in terms of memory and CPU.

Auto currying

In Lodash FP, the functions that receive an iteratee (a piece of code that expresses the data manipulation) receive the iteratee as first argument and are curried.

Functions like map() receive a single argument (the iteratee) and return a function to be called on a collection:

fp.map(x => x +1)([1, 2, 3])

Functions like reduce() function receive two arguments (the iteratee and the accumulator) and return a function to be called on a collection:

fp.reduce((a,b) => a + b, 0)([1, 2, 3])

Configuration

If you want to benefit from the immutability without changing the argument order, you can configure it:

// Every option is `true` by default.
var _fp = fp.convert({
  // Specify capping iteratee arguments.
  'cap': false,
  // Specify currying.
  'curry': false,
  // Specify fixed arity.
  'fixed': false,
  // Specify immutable operations.
  'immutable': true,
  // Specify rearranging arguments.
  'rearg': false
});

Now, Lodash FP looks like regular Lodash, excepts it doesn’t mutate data:

var a = {foo: 1};
var b = _fp.set(a, "foo", 2);
[a, b]

Installation

The installation instruction and the semantics of the functional flavor are exposed in Lodash FP Guide.