February 24, 2020



Rich Hickey, creator of Clojure


I already watched this talk more than one year ago. And today I feel very happy because I could understand 80% of that was said about transducers and better yet, 100% of the problem that transducer attempt to solve.

This is a good proxy that I am learning =)

Rich talks are always very bright and full of ideas and provocations to your day-to-day job. It’s up to you to translate them and apply succefully.

The journey continues!


What they are?

  1. extract the essence of map, filter et al

  2. away from the functions that transform sequences/collections

  3. recasting them as process transformations


What kind of processes?

  1. ones that can defined in terms of a succession or steps

  2. where each step ingests an input


Transducers are fully decoupled

  1. know nothing of the process they modify

  2. may call step 0, 1 or more times

  3. can transform input arg


Early Termination

  1. Reduction normally processes all input

  2. Sometimes a process has just 'had enough' input, or gotten external trigger to terminate

  3. A transducer might decide the same

  4. code example:

 (mapcatting unbundle-pallet)
 (taking-while non-ticking?)
 (filtering non-food?)
 (mapping label-heavy))

Code Snippet

Process to early terminate.

(defn taking-while [pred]
  (fn [step]
    (fn [r x]
      (if (pred x)
        (step r x)
        (reduced r)))))

A stateful transducer

(defn dropping-while [pred]
  (fn [step]
    (let [dv (volatile! true)]
      (fn [r x]
        (let [drop? @dv]
          (if (and drop? (pred x))
              (vreset! dv false)
              (step r x))))))))


  1. We can’t be reimplementing the same thing over and over again.

  2. Manu list fns can be defined in terms of foldr

    1. encapsulates the recursion

    2. easier to reason about and transform

  3. Transducers must support arity-0 init in terms of a call to the nested init.

Tags: clojure rich hickey functional