Clojure преобразователи поведения

С новым clojure 1.7 я решил понять, где можно использовать преобразователи. Я понимаю, какую пользу они могут принести, но не могу найти нормальных примеров написания пользовательских преобразователей с объяснениями.

Хорошо, я пытался проверить, что происходит. Я открыл документацию clojure. А там примеры использованияxf в качестве аргумента. Первое: что означает этот xf или xfrom? Этот материал производил преобразователь личности.

(defn my-identity [xf]
  (fn 
   ([]
     (println "Arity 0.")
     (xf))
   ([result]
     (println "Arity 1: " result " = " (xf result)) 
     (xf result))
   ([result input]
     (println "Arity 2: " result input " = " (xf result input)) 
     (xf result input))))

Я взял названия переменных[result input] из примера документации. Я думал, что это как в функции уменьшения, гдеresult сокращенная часть иinput это новый элемент коллекции.

Поэтому, когда я делаю(transduce my-identity + (range 5)) Я получил результат10 что я ожидал Тогда я читаю оeduction, но я не могу понять, что это. Во всяком случае я сделал(eduction my-identity (range 5)) и получил:

Arity 2:  nil 0  =  nil
Arity 2:  nil 1  =  nil
Arity 1: nil  =  nil
(0 0 1 1)

Каждый предмет дублировался, потому что я звонюxf вprintln заявление. Почему он продублировал каждый предмет дважды? Почему я получил ноль? Я всегда получу ноль, делая образование? Могу ли я передать это поведение?

Во всяком случае, я сделал

> (reduce + (eduction my-identity (range 5))
clojure.core.Eduction cannot be cast to clojure.lang.IReduce

Ок, результатEduction это НЕ сводимо, но напечатано как список. Почему это не сводимо? Когда я печатаю(doc eduction) я понимаю

Returns a reducible/iterable application of the transducers
to the items in coll.

не должны(transduce xform f coll) а также(reduce f (eduction xfrom coll)) быть таким же?

я сделал

> (reduce + (sequence my-identity (range 5))
20

Конечно получил20 из-за дубликатов. Я опять подумал, что так и должно быть(transduce xform f coll) а также(reduce f (sequence xfrom coll)) быть всегда равным, по крайней мере, в таком маленьком примере без каких-либо датчиков состояния. Это глупо, что их нет, или я не прав?

Хорошо, тогда я попробовал(type (sequence my-identity (range 5))) и получить clojure.lang.LazySeq Я думал, что это лениво, но когда я попытался взятьfirst Элемент clojure рассчитал всю последовательность сразу.

Итак, мое резюме:

1) Что означает xf или xform?

2) Почему я получаюnil какresult аргумент в то время какeduction или жеsequence?

3) Могу ли я всегда быть уверен, что это будетnil в то время какeduction или жеsequence?

4) Что такоеeduction и что за идиоматическая идея, которую нельзя привести? Или если это так, то как я могу уменьшить это?

5) Почему я получаю побочные эффекты в то время какsequence или жеeduction?

6) Могу ли я создать настоящие ленивые последовательности с преобразователями?

Ответы на вопрос(1)

Ваш ответ на вопрос