Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dissecting Transducers

Dissecting Transducers

A short talk I gave at Clojure DC October 22, 2014 on the new Clojure feature, Transducers. Also see the related github repository https://github.com/jasongilman/dissecting-transducers

Jason Gilman

October 21, 2014
Tweet

More Decks by Jason Gilman

Other Decks in Programming

Transcript

  1. What are Transducers? (map inc [1 2 3 4 5])

    Typical Map Usage: (map inc) Create a transducer by omitting the sequence:
  2. map cat mapcat filter remove take take-while take-nth drop drop-while

    replace partition-by partition-all keep keep-indexed dedupe random-sample
  3. (def doubler (map #(* % 2))) (into [] doubler (range

    5)) (sequence doubler (range)) (transduce doubler + (range 100)) (chan 10 doubler) Reusable
  4. (def xref (comp (drop-while #(< % 20)) (map #(/ %

    5.0)) (map str) (filter #(= (count %) 4)))) (into [] xref (range 100)) Composable
  5. Why are they good? • Reuse in many scenarios •

    Efficient • Use function composition • Get rid of nested lazy sequences • Use volatile!
  6. Reducing Function ‘arities • Init (0-arity) • [] => initial

    value ! • Step (2-arity)! • [result input] => result ! • Completion (1-arity)! • [result] => result
  7. Reducing Function Example ;; Init (+) => 0 ;; Step

    (+ 6 4) => 10 ;; completion (+ 10) => 10 ! (reduce + [1 2 3 4]) => 10
  8. Reducing Function Example ;; init (conj) => [] ;; Step

    (conj [0 1 2] 3) => [0 1 2 3] ;; Completion (conj [0 1 2 3 4]) => [0 1 2 3 4] ! (reduce conj [] (range 5)) => [0 1 2 3 4]
  9. ;; DON'T USE THEM THIS WAY ;; FOR ILLUSTRATION PURPOSES

    ONLY ! (def doubler (map #(* % 2))) ;; Takes a reducing function and returns one. (def rf (doubler conj)) (rf [] 5) => [10] Transducer to RF Example