Thank you all and especially @James. That is exactly what I'm missing.
Thanks again for help.

On Wednesday, September 24, 2014 5:51:09 PM UTC+2, James Reeves wrote:
>
> Reducers primarily have two benefits:
>
> 1. You don't need to create intermediate seqs
> 2. You can use them to perform a parallel fold
>
> When you use clojure.core/map, it creates a lazy seq. When you use 
> clojure.core.reducers/map, it returns a small reified object that 
> implements CollReduce.
>
> Perhaps the best way to understand what's going on is to start with the 
> normal seq functions. For instance, consider this code:
>
> (let [ys (map inc xs)]
>   (filter even? ys))
>
> In this example, an intermediate seq, ys, needs to be constructed.
>
> We can avoid this intermediate seq by using a reduce that combines both 
> steps:
>
> (reduce (fn [r x] (if (even? x) (conj r (inc x)) r) [] xs)
>
> The problem with this approach is that it's rather complected. What we 
> need is something that resolves to a reduce, but can be combined like map 
> and filter. This is where reducers come in.
>
> The main idea is to factor out that pesky conj, so we can separating the 
> reduction from the implementation details of the collection. So we can take 
> the inner reducing function:
>
> (fn [r x] (if (even? x) (conj r (inc x)) r)
>
> And then factor out conj:
>
> (fn [f] (fn [r x] (if (even? x) (f r (inc x)) r))
>
> We can then split out the filter and map to get two functions
>
> (fn [f] (fn [r x] (if (even? x) (f r x) r))
> (fn [f] (fn [r x] (f r (inc x)))
>
> And then take out even? and inc to get generic filter and map functions:
>
> (defn filterer [xf] (fn [f] (fn [r x] (if (xf x) (f r x) r))
> (defn mapper   [xf] (fn [f] (fn [r x] (f r (xf x)))
>
> So now we have the essence of map and filter, but we've removed the 
> implementation details of the collection. 
>
> Next we just need to figure out how to use these highly abstracted 
> functions. If we just want to use one of the functions, we can do so like 
> this:
>
> ((mapper inc) conj)
>
> This returns a function:
>
> (fn [r x] (conj r (inc x)))
>
> If we want to combine map and filter, we need an expression like:
>
> (fn [r x] (if (even? x) (conj r (inc x)) r))
>
> We can do this by passing the result of the mapping function into filterer 
> as f:
>
> ((filterer even?) ((mapper inc) conj))
>
> Or, we could use comp to compose the two functions, then apply conj, since 
> (f (g x)) is the same as ((comp f g) x):
>
> ((comp (filterer even?) (mapper inc)) conj))
>
> Now we can can finally create our efficient map/filter in a clean way:
>
> (let [f (comp (filterer even?)
>               (mapper inc))]
>   (reduce (f conj) [] xs))
>
> The reducer library goes one step further, and uses protocols to make it a 
> little nicer to use, but the mechanics are more or less the same.
>
> - James
>
>
> On 24 September 2014 15:30, Hussein B. <hubag...@gmail.com <javascript:>> 
> wrote:
>
>> To elaborate more,
>> I know that with reducers, map for example isn't going to create the 
>> resulting sequence by using cons. That is clear to me.
>> But, if the collections is going to call cons while reducing itself, then 
>> I'm not sure what is the benefit of reducers (besides it makes sense and 
>> makes a nice abstraction).
>>
>> Thanks.
>>
>> On Wednesday, September 24, 2014 2:58:18 PM UTC+2, Aleš Roubíček wrote:
>>
>>> Resulting function is passed to reduction function as an recipe, how to 
>>> process the data. Collections implements CollReduce protocol. When you call 
>>> reduce function it will delegate the work to concrete implementation of the 
>>> protocol.
>>
>>  -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com 
>> <javascript:>
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com <javascript:>
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to