The Rules of Transducer Club

unsorted — cgrand, 11 September 2014 @ 15 h 46 min

First rule: you don’t call a transducer.
Second rule: only composition is allowed.
Third rule: better stateful than pure.

Here are the rationale behind each rule:

First rule: you don’t call a transducer.

Transducers may be so-called “stateful” that is they create stateful reducing functions. As a consequence you should not hold onto them for too long (otherwise state goes sour…). And there’s no betetr way to not hold them for too long that to never get a hold on them at all!

That’s why transduce, sequence, iteration and chan all take a transducer to avoid you the perils of having to call it.

Second rule: only composition is allowed.

It’s a direct consequence of the first rule: you should only compose transducers.

Third rule: better stateful than pure.

This one is a bit more subtle and caused exclusively by transduce.

A reducing fn has now threes arities: [] -> acc, [acc x] -> acc and [acc] -> result.

When one wants to pass state from one step to the next there are two options: be pure and pass it in the accumulator (and you’ll use the 1-arity to clean up) or be stateful.

It turns out that the pure option is a bad one, for two reasons. First reason, it’s going to increase object churn. Second reason, it’s going to change the type of the accumulator and this is a problem because:

  • in transduce an init value may be specified and this init value must be of the type of the accumulator,
  • we don’t have a way to map from the result domain to the accumulator domain.

So it means the user has to be aware of an implementation detail of your transducer (the way you smuggle state in the accumulator) to craft a proper init value. It’s an abstraction leak, it’s bad. Be stateful.


  1. I would like to react to the third rule. I’m doing massive experiments with transducers and I was able to get around your second reason. The increased object churn does not show so far (tried it with 5 composed stateful transducers), and I get consistently better performance (up to 2 times faster) from pure approach.

    Comment by wagjo — 11 September 2014 @ 18 h 51 min
  2. Two questions regarding third rule:
    What do you mean by “object churn”?
    Is not it bad to create intermediary objects at runtime only to solve problems with declarations?

    Comment by Petr — 12 September 2014 @ 7 h 58 min
  3. […] a previous post, I explained why seeded transduce forces transducers to return stateful reducing functions. However […]

  4. […] The rules of transducer club […]

    Pingback by Transducers | Big Safari — 3 March 2015 @ 10 h 48 min

RSS feed for comments on this post. TrackBack URI

Leave a comment

(c) 2018 Clojure and me | powered by WordPress with Barecity