-->

Are Clojure transducers eager?

2020-04-07 04:32发布

问题:

In this blog entry, "CSP and transducers in JavaScript", the author states:

First, we have to realise that many array (or other collection) operations like map, filter and reverse can be defined in terms of a reduce.

So then we see a number of implementations of this in Clojure aren't lazy, they are eager:

 user> (defn eager-map [f coll]
        (reduce (fn [acc v] (conj acc (f v)))
        []
        coll))
#'user/eager-map
user> (eager-map inc (range 10))
[1 2 3 4 5 6 7 8 9 10]

My question is, are Clojure transducers eager?

回答1:

Transducers are very simple functions - they don't have a notion of laziness or, in fact, how they're applied at all. That's the beauty of the idea - with transducers, we can separate functions like map and filter from the things on which they operate.

So, yes, they can be used to build lazy sequences, as well as channels and reductions. While the transducer function call itself is eager, it's up to whatever thing you hand the transducer to to call it. Lazy sequences can lazily invoke transducers only as they're consumed while reducers will use them eagerly to spit out the reduction.

You can see in the source where sequence is used to build a lazy sequence over a collection with a transducer.