Thanks for the answers! BTW there isn't a word in the docs (http://clojure.org/transducers and http://clojure.github.io/clojure/branch-master/clojure.core-api.html#clojure.core/transduce) about the intended use of arity-1 of the reducing function f.
@Gary, thanks for suggesting to watch the talk: it's currently the only informative source on the topic. I was curious if we could transduce sequences without initial values with semigroup functions (like min or max) as is. Turns out, we can't. That's okay: the world can't be perfect :) On Friday, December 5, 2014 5:50:07 PM UTC+5, vve...@gmail.com wrote: > > I find these examples very memorable. Despite the doc strings clearly > stating the differences between transduce and reduce, one can still hastily > assume that transducing [0 1 2] will have 0 as the init argument. > > I will add that the culprit is in defining the +ten's arguments with [& > args] form, which allows the function to be called without args (or with > any number of args). > (apply + 10 []) => 10 > (+ten) => 10 > Which means these are equivalent: > (transduce (map (partial * 2)) +ten [0 1 2]) > (transduce (map (partial * 2)) +ten 10 [0 1 2]) > > Reducing [0 2 4] yields 26. With 10 as init value it yields 46. After > consuming all elements of coll, the 1-arity fn is run to provide the return > value. Due to the [& args] form the completion stage evaluates (+ten 46) > and returns 56. > > On Friday, December 5, 2014 10:51:49 AM UTC+1, Ivan Mikushin 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.