On Monday, September 4, 2017 at 3:54:14 PM UTC-5, Peter Hull wrote:
>
> I am trying to understand transducers and am reading through 
> https://clojure.org/reference/transducers I think I am missing something, 
> please can someone help?
>
> I read the part about the 'shape' of a transducer-creating-function (
> https://clojure.org/reference/transducers#_creating_transducers) and made 
> this function
>
> (defn no-op [rf]
>   (fn ([] (rf))
>     ([x] (rf x))
>     ([x r] (rf x r))))
>
> which I call with
>
> (pprint (eduction no-op (range 5)))
>
> and get 
>
> (0 1 2 3 4)
>
> This is OK. If I now define 
>
> (defn nearly-no-op [rf]
>   (fn ([] (rf))
>     ([x] (let [tmp (rf x)] (* x 2)))
>     ([x r] (rf x r))))
>
> (I want the 'finishing' function to double the answer)
>

When you say "the" answer here, that doesn't make sense to me. An eduction 
is like a 1-time (or maybe each-time would be more accurate) non-caching 
sequence. Here the values (0, 1, 2, 3 , 4) are passed to the reducing 
function in the [x r] arity when you invoke (rf x r) in nearly-no-op. The 
output of an eduction is a special kind of reducible, seqable collection. 

If you want to double "each" value you you could do that as so:

(defn nearly-no-op [rf]
  (fn ([] (rf))
    ([x] (rf x))
    ([x r] (rf x (* 2 r)))))

(eduction nearly-no-op (range 5))
;;=> (0 2 4 6 8)

If you want to like sum and then double, you want to use a transducing 
context that accumulates to a result value with a finalization function, 
you could use transduce:

(defn nearly-no-op [rf]
  (fn ([] (rf))
    ([x] (rf (* 2 x)))
    ([x r] (rf x r))))

(transduce nearly-no-op + 0 (range 5))
20

 

>
> Then (pprint (eduction nearly-no-op (range 5))) gives me a null pointer 
> exception in multiply. Where does this come from? 
>

The termination value in an eduction is just a nil, so x is nil in the ([x] 
...) arity. 

>
> If I try
>
> (defn nearly-no-op [rf]
>   (fn ([] (rf))
>     ([x] (count (rf x)))
>     ([x r] (rf x r))))
>
> then I get (0 1 2 3 4) again, i.e. the count doesn't play any part in the 
> final result.
>
> Thanks in advance!
>
> Complete program:
> (ns ttry.core
>   (:require [clojure.pprint :refer [pprint]])
>   (:gen-class))
>
> (defn no-op [rf]
>   (fn ([] (rf))
>     ([x] (rf x))
>     ([x r] (rf x r))))
>
> (defn nearly-no-op [rf]
>   (fn ([] (rf))
>     ([x] (let [tmp (rf x)] (* x 2)))
>     ([x r] (rf x r))))
>
> (defn -main
>   [& args]
>   (pprint (eduction (map identity) (range 5)))
>   (pprint (eduction no-op (range 5)))
>   (pprint (eduction nearly-no-op (range 5))))
>
>
>
>
>
>
>

-- 
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