One thing that always made me a little sad about transducers was how map lost its ability to iterate multiple collections in parallel. This is actually my favorite feature of map. For example:
(map + (range 5) (range 5 10))
=> (5 7 9 11 13)One somewhat practical use of this is if you want to compare two sequences, pairwise, using a comparator. Though I wish that every? took multiple collections, this is an adequate substitute:
(every? true? (map < (range 5) (range 5 10)))
=> trueOne somewhat esoteric use of this is to transpose a matrix:
(apply map vector [[1 2 3]
[4 5 6]])
=> [[1 4]
[2 5]
[3 6]]However, transducers can only be applied to a single source...or can they?
I noticed that map's transducer takes a fourth arity with a variable number of items. This really surprised me since as far as I could remember there were no transducing contexts that would actually work with multiple sources...or where there?
I looked through transduce, eduction, into, and sequence and found that sequnece can take multiple collections.
Neither map's fourth arity nor sequence taking multiple collections is mentioned in any of the transducer documentation. The only hint is sequence's docstring mentions multiple collections, but you'd have look at the source for map to see the fourth arity.
map is the only clojure.core transducer with a fourth arity, and sequence is the only clojure.core transducer context to supply multiple sources, so this seems to be of limited use. However, as long as map is the first stage of your transducer pipeline you can use other transducers with a multi-collection invocation of sequence:
(sequence (comp (map +)
(filter even?))
(range 5)
(range 5 10)
(range 10 15))
=> (18 24)This makes me happy!