Specter is a library for Clojure/ClojureScript that makes it simple to navigate through and change nested data. It’s a ‘swiss army knife’ for handling complex data structures.
With it you can:
Query values in a nested structure
Change each key or value in a nested map
Change each value in a nested sequence
Append or prepend values in a nested map or sequence
Add (or remove) a value at a specific place in a map or sequence
Specter is amazing, well worth the time to learn it. My article is really just scratching the surface … there are more advanced capabilities to discover! Feedback welcome - maybe use-cases not covered?
I’d love to hear some real-world use cases where this came in handy. I haven’t come across any deeply nested structures in a while, and I love hearing war stories.
At my previous job, I had to work with measurement data (WebRTC QoS metrics) that needed to be aggregated into a deep hierarchical structure. At the lowest level, there were measurement data, on top of that there were quality of experience estimates for each media stream, then for combined audio-visual quality, and so on, with several end-points to be considered at each level, and metadata for performing root cause analysis when things went south, quality-wise. Flattening this structure didn’t make sense, from the point of view of the computations needed, but handling it with the vanilla Clojure functions would’ve been a nightmare. With Specter, the whole thing boiled down to taking the original structure, sticking it inside a thread-last form, and performing a level-wise calculation with Specter’s transform at each step. It turned out to be much clearer and simpler, I think.
Getting to the point that it was comfortable to write the paths did take some time, though.
In my current job I’m using it in simpler cases, but with a similar premise. I have a tree with a couple of levels, and need to update leaves or internal nodes, or sometimes rename keys. I’ve found that for these cases it’s a great tool.