Reducing functions have three arities:

0-arity: returns the initial state
1-arity: handles completion
2-arity: reduce step function

Using arities to denote different functionality is a little odd, but it
does make sense for functions like addition and conjoin:

    (+) => 0
    (+ 1) => 1
    (+ 1 2) => 3

    (conj) => []
    (conj [1]) => [1]
    (conj [1] 2) => [1 2]

The 1-arity state is often just the identity function, but for channels and
I/O processes it's useful for closing resources, flushing buffers and
generally cleaning up after itself.

You're getting strange results because your reducing function is strange.
You're not thinking about how the different arities are used.

Look at it another way:

    (defn +ten
      ([] 10)  ;; initial state is 10
      ([x] (+ 10 x))  ;; on completion, add 10
      ([x y] (+ 10 x y))   ;; step function adds x and y and 10

So let's take a look at your initial transduce again:

    (transduce (map (partial * 2)) +ten [0 1 2])

You're essentially saying:

"Set the initial value to 10. Double the values in the array and add then
together in pairs. Every time you add a pair of numbers, add 10 to the
result. On completion, add 10 again."

- James

On 5 December 2014 at 09:51, Ivan Mikushin <i.mikus...@gmail.com> wrote:

> First: transducers are a very cool idea, and I'm really looking forward to
> clojure 1.7 release when we'll be able to use them in production code.
>
> Now, clojure 1.7 is still alpha, so here's my feedback while it's not
> (too) late.
>
> transduce has a pretty unintuitive behaviour. Suppose, you've got some
> transformation, which you are going to apply to your reducing function and
> finally use it to reduce a collection. Currently, you have to know the
> implementation detail of transduce to approach this task.
>
> Just a couple examples.
>
> Example 1:
> (defn +ten [& args]
>   (println (str "+ten " args))
>   (apply + 10 args))
>
> (transduce (map (partial * 2)) +ten [0 1 2]) ;; Should equal *26*, right?
> +ten
> +ten (10 0)
> +ten (20 2)
> +ten (32 4)
> +ten (46)
> => *56*
>
> (transduce (map (partial * 2)) +ten 0 [1 2]) ;; OK, now this SHOULD equal
> *26*...
> +ten (0 2)
> +ten (12 4)
> +ten (26)
> => *36*
>
> (transduce (map (partial * 2)) +ten []) ;; Let's see: just no-args (+ten)
> *once* here...
> +ten
> +ten (10)
> => *20*
> WAT?
>
> Example 2:
> (transduce (map (partial * 2)) max 0 [1 2])
> => *4*
> (transduce (map (partial * 2)) max [0 1 2]) ;; Should give *4*...
> *ArityException Wrong number of args (0) passed to: core/max
>  clojure.lang.AFn.throwArity (AFn.java:429)*
> WAT?
>
> I know transduce requires f to accept arity 1 (as well as 0 and 2).
> Looking at the current implementation (
> https://github.com/clojure/clojure/blob/clojure-1.7.0-alpha4/src/clj/clojure/core.clj#L6518),
> we can see this arity is applied just before returning result. Why?
>
> Why not use it (okay, (xform f)) when there's no init AND coll has just
> one element.
>
>  --
> 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.
>

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