Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transducer's init not called

I am writing a custom transducer as an exercise, but I am surprised to see that its 0-arity init function is not called.

Why?

Is it related to which aggregation function I am using? If yes, which ones would call the init function and why others are not?

(defn inc-xf [xf]
  "inc-xf should be equivalent to (map inc)"
  (fn
    ;; init
    ([]
     (println "init") ;; <- this is not called (???)
     (xf))

    ;; step
    ([result input]
     (println "step" result input)
     (xf result (inc input)))

    ;; completion
    ([result]
     (println "completion" result)
     (xf result))))

(transduce inc-xf
           +
           100
           [5 5 5])
like image 337
Vincent Cantin Avatar asked Feb 18 '18 05:02

Vincent Cantin


1 Answers

If you look at the implementation of transduce you can see what happens.

(defn transduce
  ;; To get the init value, (f) is used instead of ((xform f))
  ([xform f coll] (transduce xform f (f) coll))
  ([xform f init coll]
   ,,,))

Why, however, is more difficult to answer.

Transducers implementing the zero arity is part of the requirements for a transducer, but it is never actually used in any transducing context in clojure.core. On the mailing list there's been a post asking the same question as you and proposal of an implementation of transduce that actually uses the init arity. The jira ticket was declined, however, with the explanation:

Rich asked me to decline the ticket because the init arity of the xform should not be involved in the reducing function accumulation. - Alex Miller

Why, then, is the init arity part of the contract for a transducer if it's not used anywhere? ¯\_(ツ)_/¯

like image 79
madstap Avatar answered Nov 03 '22 09:11

madstap