Let's say I have several vectors
(def coll-a [{:name "foo"} ...]) (def coll-b [{:name "foo"} ...]) (def coll-c [{:name "foo"} ...]) and that I would like to see if the names of the first elements are equal.
I could
(= (:name (first coll-a)) (:name (first coll-b)) (:name (first coll-c))) but this quickly gets tiring and overly verbose as more functions are composed. (Maybe I want to compare the last letter of the first element's name?)
To directly express the essence of the computation it seems intuitive to
(apply = (map (comp :name first) [coll-a coll-b coll-c])) but it leaves me wondering if there's a higher level abstraction for this sort of thing.
I often find myself comparing / otherwise operating on things which are to be computed via a single composition applied to multiple elements, but the map syntax looks a little off to me.
If I were to home brew some sort of operator, I would want syntax like
(-op- (= :name first) coll-a coll-b coll-c) because the majority of the computation is expressed in (= :name first).
I'd like an abstraction to apply to both the operator & the functions applied to each argument. That is, it should be just as easy to sum as compare.
(def coll-a [{:name "foo" :age 43}]) (def coll-b [{:name "foo" :age 35}]) (def coll-c [{:name "foo" :age 28}]) (-op- (+ :age first) coll-a coll-b coll-c) ; => 106 (-op- (= :name first) coll-a coll-b coll-c) ; => true Something like
(defmacro -op- [[op & to-comp] & args] (let [args' (map (fn [a] `((comp ~@to-comp) ~a)) args)] `(~op ~@args'))) - Is there an idiomatic way to do this in clojure, some standard library function I could be using?
- Is there a name for this type of expression?