Specter ⚡️

Specter is simply one of the most powerful libraries and I agree with its tagline Clojure(Script)'s missing piece.

Here's an amazing talk from the author, where he explains his rationale behind the need for such a framework. If you are dealing with data structures, you'd want to use specter as it exposes a simple API for working with them which is easily extensible. There are many examples in the talk as well as here.

It is batteries included to work with most structures, and the whole power of it comes from a simple idea.

Here's a short version:

s/select or s/transform cover most of the use cases. Whatever the scenario, you are almost always navigating to a place in a data structure and use(select) it or manipulate(transform) it. So what actually specter is its

A protocol which is an interface to implement a navigator and it provides efficient means to compose those together.

Keywords here being: navigator and compose.

Defining the navigator is just implementing a protocol which is how to do rest of selection/transformation from the sub value from this current point. Here's an implementation of a keypath navigator which navigates/transforms to a key in a map(parameterised by akey)

(defpath keypath [akey]
    (select* [this structure next-fn]
             (next-fn (get structure akey)))
    (transform* [this structure next-fn]
             (assoc structure
                    akey (next-fn
                             (get structure akey)))))

The select* part of the code is saying, "this is the thing you need to do(get) to extract the sub-structure(sub-value) that is needed and apply the next-fn." Similarly, transform* it says, "this is how you apply a transformation(next-fn) on the current structure".

And violà; this idea is applied to every navigator and the best part is, it's completely agnostic to the structure and next-fn, making it a composable framework.

I think it really helps to think where can I get the data, and what I'll do with it than worrying about how to repack the data into a specific format(de-coupling navigation and repacking). More about performance here. It can be as good or better than using the default functions.

Last updated