Fork me on GitHub
#specter
<
2017-01-04
>
gdeer8116:01:25

when you have a bunch of maps and you want to make all of the maps agree on a unit of measure you have to convert the value for one key to another and remove the old key like, `[{:place "here" :degrees-celsius 32} {:place "there" :degrees-faren 100}]` you have to do something like `(dissoc (assoc mymap :degrees-celsius (f->c (:degrees-faren mymap)) :degrees-faren))` you could split that out into a general function that takes a key and a conversion function and my implementation probably isn't very idiomatic, but I'm sure there is a way to do this in specter I just can't seem to quite get it

gdeer8116:01:53

it's such a common thing I'm sure someone has a recipe for this kind of transform

schmee17:01:21

hello! I’m trying to figure out how to annotate the depth of a tree with specter

schmee17:01:39

so something like

``````(= (depth-counter [:a [:b [:d] [:e]] [:c [:f]]])
[{:val :a :depth 0}
[{:val :b :depth 1}
[{:val :d :depth 2}]
[{:val :e :depth 2}]]
[{:val :c :depth 1}
[{:val :c :depth 2}]]])
``````

schmee17:01:28

looking at the readme I don’t see any immediate way to carry state when navigating, but I’m sure I just haven’t figured out how yet 🙂

schmee17:01:08

or wait, `collect` seems like something...

nathanmarz17:01:19

@gdeer81 you could make a navigator that navigates to the k/v pair and replaces it with a new k/v pair

nathanmarz17:01:44

so something like `(transform (kvpair :degrees-faren) (fn [[_ v]] [:degrees-celsius (k->c v)]))`

nathanmarz17:01:42

@schmee yea you should be able to just collect nodes as you go, and then use the count of the collected values list to annotate the depth

nathanmarz17:01:26

``````(def data [:a [:b [:d] [:e]] [:c [:f]]])

(def TreeWalker
(recursive-path [] p
(stay-then-continue
VAL
(if-path vector?
[ALL p]))))

(transform [TreeWalker (complement vector?)]
(fn [& vals]
{:depth (- (count vals) 2)
:val (last vals)})
data)
``````

gdeer8117:01:54

so the naming convention is unparameterized navigators are in all caps else it follows regular function naming conventions?

schmee17:01:09

nathanmarz thank you so much for that example!

schmee17:01:25

I’m just trying out Specter for the first time and this stuff is blowing my mind already!

schmee17:01:45

such a breath of fresh air after dealing with zippers 😛

nathanmarz17:01:49

zippers are still useful but not for the majority of use cases

nathanmarz17:01:59

(zippers are integrated with specter in com.rpl.specter.zipper)

schmee17:01:02

am I correct in thinking that `recursive-path` is just a shorthand for declarepath + providepath?

schmee17:01:09

(there are no docs for that macro)

nathanmarz17:01:01

`local-declarepath` + `providepath`

gdeer8118:01:14

@nathanmarz if I write this kvpair navigator do you think it would be useful to add to specter or is it too specific to this one use case? I remember you saying in your talk that most of the functionality that is in specter is from your specific needs so

nathanmarz18:01:46

@gdeer81 doesn't seem common enough to add to the core

gdeer8118:01:56

okay then I guess it will just end up in a gist and if someone needs it, it will show up in their google results 😆

gdeer8118:01:16

Okay, so specter is good for ETL, but what about analytics? like `{:usa-census [{:state "Texas" :population 20000000} {:state "California" :population 40000000} ...}] :mexico-census [{:state "Coahuila" :population 200000} {:state "Mexico City" :population 20000000} ...]}` transformed into `{:us-total-pop 3241118787 :mexico-total-pop 128632004 ...}`

gdeer8118:01:03

basically a collection of maps and you aggregate on one of the keys

gdeer8118:01:33

The Clojure that I have for this looks really gnarly

nathanmarz18:01:13

that's outside the scope of specter

gdeer8118:01:43

I guess I could write a function that uses specter to collect the values for each key I'm aggregating