specter

Andrew Wilcox 2025-09-24T08:57:32.169629Z

What is the difference between (compact x y z) and (compact [x y z])? I have a data structure {"u1" ["c1" "c2" "c3"], "u2" ["c4"]} where I want to remove a particular item from any of the vectors, and then I want to remove the map key if the vector is then empty. (s/setval [(s/compact s/MAP-VALS [s/ALL (s/pred= "c4")])] s/NONE {"u1" ["c1" "c2" "c3"], "u2" ["c4"]}) appears to work but I don't understand why. Why (s/compact s/MAP-VALS [s/ALL ...]) vs. (s/compact s/MAP-VALS s/ALL ...) vs. (s/compact [s/MAP-VALS s/ALL ...]) ?

nathanmarz 2025-09-24T19:02:34.187949Z

all compact does is interleave checking for empty and converting to NONE after each navigator https://github.com/redplanetlabs/specter/blob/master/src/clj/com/rpl/specter.cljc#L1501

👍 1
nathanmarz 2025-09-24T19:02:43.580609Z

so (compact x y z) will do it after x, y, and z

👍 1
nathanmarz 2025-09-24T19:03:25.188349Z

(compact [x y z]) will do it only after the entirety of [x y z] completes, so it will only apply where navigation starts for the whole subpath

👍 1
nathanmarz 2025-09-24T19:04:15.700859Z

user=> (setval [:a (compact :b :c)] NONE {:a {:b {:c 1}}})
{}
user=> (setval [:a (compact [:b :c])] NONE {:a {:b {:c 1}}})
{:a {:b {}}}