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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.