Fork me on GitHub

as we’re talking about dissocing, I have a doubt as well 😆 I need to dissoc a key from every map that has it in a nested structure, so if I want to dissoc :a, {:a “le”, :c {:a “lu”, :b “la”}} should become {:c {:b “la”}}. I tried doing (transform (walker coll?) #(dissoc % :a) ds), but the walker stops on the first level and the transform returns {:c {:a “lu”, :b “la”}}. is there an easy way to do this?


oh, nvm. just saw params-reset for declaring recursive navigators

Chris O’Donnell00:09:01

@caio: I don't think you need params-reset. Here's what I came up with, though I'm trying to think of a better way.

=> (declarepath MapWalker)
=> (providepath MapWalker (if-path map? (continue-then-stay MAP-VALS MapWalker)))
=> (transform MapWalker #(dissoc % :a) {:a 0 :b {:a 1 :b 2}})
{:b {:b 2}}

Chris O’Donnell00:09:29

Yeah, here's a shorter implementation: (providepath MapWalker (continue-then-stay MAP-VALS map? MapWalker))


Oh, nice. Didn't knew this continue-then-stay. Thanks!


for those interested, I rewrote almost all of Specter's core


25% smaller codebase, better performance, and no more restrictions on what can be inline compiled/cached (locals, special forms, and dynamic vars in nav positions can now be inline compiled/cached)


@codonnell the code you sent me actually breaks when there are other nested structures other than maps (vectors for instance). for instance:

=> (transform MapWalker #(dissoc % :a) {:a 0 :b [{:a 1 :b 2}]})
{:b [{:a 1 :b 2}]}
. after some time, this is what I got:
(declarepath map-walker)
(providepath map-walker [(walker map?)
                         (continue-then-stay MAP-VALS map-walker)])
now it’s working fine 🙂


Hello I'm new to specter, and I'm trying to move a keyword from one path to another. so far I have this working but I can't tell if it is the specter way, and I have a feeling i'm doing it wrong:

(defn remover [& n]
  (fn [coll] (into (empty coll)
                   (remove (set n) coll))))

(->> {:a [1 2 3] :b [4]}
     (transform [:a] (remover 2))
     (setval [:b BEGINNING] [2]))


I'd like to be able to reference the 2 in this example from inside the paths themselves. is that a thing? I've been reading the docs and having trouble finding something that addresses this

Chris O’Donnell16:09:36

@escherize: To add onto the beginning of a sequence with specter, it's more idiomatic to do (setval [:b BEGINNING] [0] [1 2 3])


thanks, I thought conjer was a bit much. I'll update the example

Chris O’Donnell17:09:07

Other than that, your approach looks fine to me.


That's good to hear, thanks @codonnell


but is there a way to bake the 2 into the path itself?

Chris O’Donnell17:09:00

Yes @escherize. Transform functions receive as their initial arguments any collected values.

Chris O’Donnell17:09:31

=> (transform [(putval #{2 3 5}) :a] remove {:a (range 10)})
{:a (0 1 4 6 7 8 9)}


ohhh. I see! that's fantasic, thanks @codonnell !

Chris O’Donnell18:09:59

@nathanmarz are you planning on a blog post/wiki page about the 0.13.0 changes similar to the post about 0.11.0's optimizations?


@codonnell the inline caching implementation is completely different now


@codonnell I need to get the new design working for cljs first