Hi all, I am currently testing performance of different reduce and map implementations in my programs and have problems because their treatment of nil is different. The "normal" clojure.core implementations of reduce and map work well when called on nil, but reduce-kv and functions in clojure.reducers throw exceptions.
--- snip --- user=> (defn fold-into-vec "Provided a reducer, concatenate into a vector. Note: same as (into [] coll), but parallel." ([coll] (r/fold (r/monoid into vector) conj coll)) ([n coll] (r/fold n (r/monoid into vector) conj coll))) user=> (map (fn [el] (* 2 el)) nil) () user=> (mapv (fn [el] (* 2 el)) nil) [] user=> (fold-into-vec (r/map (fn [el] (* 2 el)) nil)) #<IllegalArgumentException java.lang.IllegalArgumentException: No implementation of method: :coll-fold of protocol: #'clojure.core.reducers/CollFold found for class: nil> user=> (reduce (fn [ret el] (+ el el)) {} nil) {} user=> (reduce (fn [ret [k v]] (+ k v)) {} nil) {} user=> (reduce-kv (fn [ret k v] (+ k v)) {} nil) #<IllegalArgumentException java.lang.IllegalArgumentException: No implementation of method: :kv-reduce of protocol: #'clojure.core.protocols/IKVReduce found for class: nil> --- snip --- I find this behaviour quite unfortunate because I now have to explicitly test for nil? and ensure consistent behaviour. This inconsistency violates the principle of least-surprise and I am not sure if the current behaviour is intentional or merely an unfortunate implementation detail. Wouldn't it make sense if reduce-kv and r/map mirror the behaviour of reduce, map and mapv in core? P.S. Would it be possible to have something like fold-into-vec in clojure.reducers? -- Wolodja <babi...@gmail.com> 4096R/CAF14EFC 081C B7CD FF04 2BA9 94EA 36B2 8B7F 7D30 CAF1 4EFC
signature.asc
Description: Digital signature