Meiosis Wiki

Table of Contents

Lodash FP

In this part of Meiosis, we will look at different strategies for model updates and nesting components. Keep in mind that Meiosis is very flexible; you can use plain mutation for model updates if that suits you. That being said, let's explore some libraries that can make model updates and nesting quite elegant.

Curried Functions

In our temperature component example, we had an action to edit the date in the text field:

editDate: evt =>
  update(model => {
    model.date = evt.target.value;
    return model;
  })

With Lodash, we can write this as:

editDate: evt => update(model => _.set(model, "date", evt.target.value))

We can make this even nicer using Lodash-FP.

The lodash/fp module promotes a more functional programming (FP) friendly style by exporting an instance of lodash with its methods wrapped to produce immutable auto-curried iteratee-first data-last methods.

The key parts are auto-curried and data-last.

A curried function is a function that accepts multiple parameters, but, when passed less than the total number of parameters, returns a function that accepts the remaining parameters. When all parameters have been provided, the function returns its result.

So, given a function const f = (x, y, z) => x + y + z, a curried version of f could be called in any of these ways:

f(10, 20, 30)
f(10)(20, 30)
f(10, 20)(30)
f(10)(20)(30)

Curried functions make it easy to create functions by passing less than the total number of parameters. A simple example is a curried function const add = (x, y) => x + y. You could write const increment = add(1) and then re-use increment to add 1 to any number, by calling const incremented = increment(number).

Data-Last Functions

Data-last functions change the order of their parameters to put the "configuration" parameters first and the "data" parameters last. If you look at Lodash's _.set function:

_.set(model, "value", value)

It sets the "value" property to value on the model. That's the important part: it operates on the model. The model is the data. In Lodash-FP, the order of the parameters is changed to:

_.set("value", value, model)

Notice how model is now the last parameter. How does this help? Combined with currying, we can improve our _.set call. Previously we had:

editDate: evt => update(model => _.set(model, "date", evt.target.value))

Using Lodash-FP, we now have:

editDate: evt => update(model => _.set("date", evt.target.value, model))

Point-Free Style

A pattern that often occurs when passing functions is:

update(x => f(x))

You are passing a function that gets x and calls f(x). But, you don't need to create a new function here. You can just pass f directly:

update(f)

Since f is already a function that accepts a parameter and returns a result.

We can apply this to our code:

editDate: evt => update(model => _.set("date", evt.target.value, model))

Since _.set is curried, we can call it with just the first two parameters, to get a function of one parameter:

editDate: evt => update(model => _.set("date", evt.target.value)(model))

We have the same pattern here, update(x => f(x)), where f is _.set("date", evt.target.value), so we can simplify it to update(f):

editDate: evt => update(_.set("date", evt.target.value))

Since it is curried, _.set("date", evt.target.value) returns a function of model, which we can pass to update. Notice that we don't need to specify the model parameter at all! This is called point-free style.

Principles / Takeaways

Up Next

Having learned these functional programming concepts, next we'll look at Ramda, another library with excellent functional programming support.

Table of Contents


Meiosis is developed by @foxdonut00 / foxdonut and is released under the MIT license.