Fork me on GitHub
#specter
<
2016-08-10
>
achesnais12:08:01

@nathanmarz: I wonder, any best practices on aliasing specter? I find that having the split between specter and specter.macros prevents from efficiently aliasing everything under one ‘specter’ alias. I really like using ns aliases for any non-core library I use, to improve readability/non-ambiguity in my code. Is this split due to the treatment of macros in Clojurescript?

nathanmarz12:08:21

@achesnais: yes, it was done for cljs

sebastianpoeplau15:08:59

is there a way to do something like "insert or update" on a vector? let's say I have a vector [{:name "Test"} {:name "Whatever"}] and I would like to run f on the element that satisfies #(= "Something" (:name %)) (or create it, as in this case it doesn't exist)

sebastianpoeplau15:08:54

I've been playing with nil->val but when my predicate doesn't match on any element of the vector I get an empty vector and not nil

achesnais16:08:50

@nathanmarz: thanks 🙂

mattsfrey18:08:04

hello, wondering if anyone knows how to replicate

(update-in db [:contacts :show-modal?] assoc true)
using transform

mattsfrey18:08:55

I tried

(transform [:contacts] #(assoc % :show-modal? true) db)
and it seems to be doing transformations to much of the db for some reason

mattsfrey18:08:13

nvm it is working, was another issue

mattsfrey18:08:43

but in the same vein, is there a more efficient or elegant way to write that^^ ?

nathanmarz18:08:20

@sebastianpoeplau: can you show an example of the input/output you're looking for?

nathanmarz18:08:53

@mattsfrey: (setval [:contacts :show-modal?] true db)

mattsfrey19:08:03

ah that is nice, does it get the 6x performance of transform etc though?

mattsfrey19:08:14

or is that not a good example for comparison

nathanmarz19:08:18

@mattsfrey: yes, that will be much faster than update-in

nathanmarz19:08:05

the new update-in in 1.9 is much better but specter still outperforms it

mattsfrey19:08:19

oic, good to know, thanks!

sebastianpoeplau21:08:57

@nathanmarz: of course - say I have (defn f [person] (assoc person :some "value")), then I would like the transformation to return [{:name "Test" :some "value"} {:name "Whatever"}] when called on input [{:name "Test"} {:name "Whatever"}], and it should return the same value when used on input [{:name "Whatever"}]. that is, it should update the entry that has :name "Test" or insert it if it's not in the vector

sebastianpoeplau21:08:24

my best guess so far is the following:

(setval [(not-selected? ALL #(= "Test" (:name %))) END] [{:name "Test"}]) ; insert if necessary
(transform [ALL #(= "Test" (:name %))] f my-vector) ; apply my function

sebastianpoeplau21:08:15

I'm just realizing that I could change the lambda #(= "Test" (:name %)) to :name #(= "Test" %), but the question is still whether I can accomplish both steps, insertion and transformation, in one go

nathanmarz21:08:59

@sebastianpoeplau: I think doing it the way you're doing it is the cleanest approach

nathanmarz21:08:03

I would recommend factoring out [ALL #(= "Test" (:name %)))] into a composite navigator and re-using it in each call

nathanmarz22:08:38

@sebastianpoeplau:

(def person-nav (comp-paths ALL (paramsfn [id] [p] (= id (:name p)))))

(setval [(not-selected? (person-nav "Test")) END] [{:name "Test"}] my-vector)
(transform (person-nav "Test") #(assoc % :some "hi") my-vector)