I'm currently learning clojure
for fun and today I run into this article about reducers. I find it not only interesting but tricky to me. As a beginner:
I know how to use core map
, filter
, reduce
I understand that core/map
, core/filter
... return a sequable
col
Rich Hickey mentioned core.reducers/map
... return a reducible
col
Because the implementation of core/map
... and core.reducers/map
... look very identical. My question is
How does reducible
col make difference in layman's term?
Can anyone give me some trivial examples of reducible
function?
Thank you so much
For me, the main idea of reducers is that they actually do less than map
/filter
/reduce
. Reducers do not specify if they execute lazily or eagerly, in serial or in parallel, on a collection or on another type of data structure and what they produce may be a collection or something else. Examples:
map
/filter
/reduce
must be passed a collection and must produce a
collection; a reducer does not have to do either. This idea of reducers is
extended in transducers so that the same transducer can applied to either
a collection or a core.async
channel.
Reducers also do not specify how they are executed.
map
/filter
/reduce
always execute in a serial manner across a
collection; never in parallel. If you want to execute across a
collection in parallel, you must use a different function: pmap
. You
could imagine that if you wanted to filter in parallel, you could
also create a function pfilter
(this doesn't exist but you could write it).
Instead of creating a parallel version of each function, reducers simply say
"I don't care how I'm executed" and it's up to another function (fold
in the case of reducers) to decide if the execution should be done in parallel or not.
fold
is more general than pmap
because the reducers that it applies to can
do filtering or mapping (or composed to do both).
In general, because reducers make fewer assumptions about what they apply to, what they produce or how they are applied, they are more flexible and therefore can be used in a wider variety of situations. This is useful because reducers focus on "what your program does" rather than "how it does it". This means that your code can evolve (e.g. from a single thread to a multi thread or even to a distributed application) without having to necessarily touch the part of the program that forms the core logic of what your code does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With