Recommended listening during read: spotify:track:3bCmDqflFBHijgJfvtqev5

Tl;dr

Lenses are pretty useful to dig deep into data structures and make changes in a pure functional way. Immutable.js and lenses are a great fit because they provide us with a universal api for working with built in and immutable data structures. We can also convert between built in and Immutable.js structures with isos which makes library interop easier.

Prereq

I’m going to be assuming some knowledge of ramda, which implies understanding the basics of currying and composition. If you’re not familiar, you may want to first read http://fr.umio.us/why-ramda/

Here’s the import section for this post if you want to run each example*

Through the Looking-Glass

What is a lens? Well, it’s a getter/setter pair. Okay, they are more than that, but for now think of them as such. Let’s first define some data, then play around with one.

This data consists of a user, Charles, who has two suspiciously simple addresses. What are you hiding, Charles?

Basic usage

Now we must define a lens to access properties on this data… let’s use lensProp to make a name lens.

As the examples suggest, name does nothing on its own. It must be used with another function like view, set, or over.

view(name) amounts to prop(‘name’) in this situation. What is interesting, though, is set and over — they preserve the whole data structure despite the alterations. They are also pure (hence, immutable) setters so we needn’t worry about bugs and the cognitive load arising from mutable state.

This isn’t the most efficient setter if you want to change hundreds of records (in that case use immutable.js like below), but it’s a great, cheap way to get an immutable change and I’ll bet it has no measurable performance difference at all in your application.