Fork me on GitHub
#specter
<
2016-08-03
>
borkdude07:08:01

is it possible to transform the keys in a map on just one level with specter?

borkdude07:08:22

for example {:a 1, :b {:c 2}} => {:aa 1, :bb {:c 2}}

borkdude10:08:07

(defnav KW-NS []
  (select* [this kw next-fn]
    (next-fn (namespace kw)))
  (transform* [this kw next-fn]
    (let [kw-name (name kw)
          new-ns (next-fn (namespace kw))]
      (keyword new-ns kw-name)
      )))

(setval [ALL FIRST KW-NS] "user" {:a 1 :b 2 :c 3})
;; => {:user/a 1, :user/b 2, :user/c 3}

borkdude10:08:13

how does it work?

nathanmarz10:08:31

so KW-NS navigates to the namespace portion of a keyword

nathanmarz10:08:55

is it the defnav portion that you're asking about in particular?

nathanmarz10:08:16

there's two code paths, one for select and one for transform

nathanmarz10:08:27

select must call next-fn on the "navigated to value(s)"

nathanmarz10:08:42

in this case, it's just (next-fn (namespace kw))

borkdude10:08:52

@nathanmarz: what is next-fn in the example with setval?

nathanmarz10:08:11

it's the rest of the navigation + final transformation

nathanmarz10:08:25

so in this case next-fn will be (fn [v] "user")

nathanmarz10:08:47

if there was more navigation after KW-NS, it would be the transform* code paths for the subsequent navigators

borkdude10:08:54

@nathanmarz: specter takes constants and interprets it as a function?

nathanmarz10:08:05

setval is a thin wrapper around transform

nathanmarz10:08:43

(setval [ALL FIRST KW-NS] "user" {:a 1 :b 2 :c 3}) == (transform [ALL FIRST KW-NS] (fn [_] "user") {:a 1 :b 2 :c 3})

borkdude10:08:56

ok understood that part

borkdude10:08:23

I think I'll just have to read up on the defnav docs

nathanmarz10:08:56

that's the core of how specter works

nathanmarz11:08:20

your linear path of navigators becomes a single nested function

borkdude11:08:40

I think I'm getting it, but you could also have written: (transform [ALL FIRST] (fn [kw] (keyword "user" (name kw)))) right? but your example is more abstract

nathanmarz11:08:08

much more reusable and composable

borkdude11:08:18

cool stuff 🙂

borkdude11:08:43

any reason specter is still using cljx? compatibility with previous clj versions?

nathanmarz11:08:09

though finally dropping support for 1.6 as of specter 0.12.0

nathanmarz11:08:20

just need to do the work now of porting to cljc