This episode is for subscribers only. Sign Up or Log in to watch it.

38. Transducers

Published 19 January 18

Transducers are a Clojure feature allowing you to write code that is efficient, reusable, and composable. They have been around for several years, landing first in Clojure 1.8, but even some experienced Clojure programmers are not yet reaping the benefits of their use. In this episode we’ll look at the problems that Transducers solve, and how you use them in practice.

Show notes

Transducers have a reputation of being complicated. I think this is unfair. Sure, writing your own transducers isn’t trivial, but I can demonstrate how to use them in under a minute.

Suppose I need all odd numbers from zero to twenty. I can do this with straightforward Clojure using filter

(filter odd? (range 20))
;;=> (1 3 5 7 9 11 13 15 17 19 ...)

You can think of filter as performing three steps. It unpacks the input collection, grabbing each element in turn, it then does its actual job of applying the predicate to test if the element should be filtered or not, and finally it adds the element to the output collection.

+---------------+   +-----------------+   +---------------+
| Unpack input  |==>| Check predicate |==>| Create output |
|  collection   |   |                 |   |  collection   |
+---------------+   +-----------------+   +---------------+

Now I’ll do the exact same thing with a transducer, I first change the call to filter to only take a single argument. When you call filter this way it returns a “transducer” which filters odd numbers. Pass the transducer and the collection argument to sequence, and you get the same result as before. A lazy sequence of all odd values in the given range.

(sequence (filter odd?) (range 20))
;;=> (1 3 5 7 9 11 13 15 17 19)