Specter fills in the holes in Clojure's API for manipulating immutable data, allowing data manipulation to be done concisely and with near-optimal performance. Specter is especially powerful for working with nested and recursive data.
Excited to be releasing Specter 1.1.0 today. It's not often I discover how to do something new with Specter, but this release includes the `compact` navigator which utilizes a new composition technique.
If you look at the JIRA for a proposed `dissoc-in` function (
https://dev.clojure.org/jira/browse/CLJ-1063), you can see a discussion about whether empty subvalues should be kept or discarded. This is further complicated by the fact that `dissoc-in` must operate on vectors. Ultimately, there is no right answer, as the manipulation needs can differ from usage to usage. You may even want to remove some empty subvalues along the path but not others. The JIRA discussion looks to handle the most common use case instead of handling all use cases.
Specter's paths, on the other hand, can specify much richer behavior. The new `compact` navigator allows you to concisely specify which values along the path should be removed if emptied:
(setval [:a (compact :b :c)] NONE {:a {:b {:c 1}}})
;; => {}
(setval [:a (compact :b :c)] NONE {:a {:b {:c 1} :d 2}})
;; => {:a {:d 2}}
(setval [:a :b (compact :c)] NONE {:a {:b {:c 1}}})
;; => {:a {}}
It works with sequences too:
(setval [1 (compact 0)] NONE [:a [:b] :c])
;; => [:a :c]
And like all navigators, it works recursively as well:
(def TREE-VALUES
(recursive-path [] p
(if-path vector?
[(compact ALL) p]
STAY
)))
(setval [TREE-VALUES even?] NONE [1 [2 3] [4] [5 [[6]]]])
;; => [1 [3] [5]]
The new composition technique is utilizing terminal navigation points inside a reusable navigator. Terminal points were originally conceived for `multi-transform` operations, but to my pleasant surprise turn out to be very useful beyond that.
I don't usually expound on releases like this, but the `compact` navigator, a composition of already existing components, excited me because it shows Specter is more powerful than even I knew.