未调用传感器的初始化

Transducer's init not called

我正在编写一个自定义转换器作为练习,但我很惊讶地发现它的 0 元初始化函数没有被调用。

为什么?

是否与我使用的聚合函数有关?如果是,哪些会调用 init 函数,为什么其他的不会?

(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])

如果您查看 transduce 的实现,您会看到发生了什么。

(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]
   ,,,))

然而,为什么更难回答。

实施零元数的传感器是 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 的一部分,但被拒绝,解释如下:

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

那么,如果换能器未在任何地方使用,为什么它是合同的初始部分? ¯\_(ツ)_/¯