Hi all, I've had a case where reduce with merging operations throws errors on lazy sequences. I thought I should check in for insight before logging a bug. Maybe using maps as keys has something to do with it. too (I've since refactored)
(reduce merge-student-demand everybody) Throws: IllegalArgumentException contains? not supported on type:clojure.lang.LazySeq clojure.lang.RT.contains (RT.java:814) However: (reduce merge-student-demand (take 5 everybody)) works just fine. As does: (merge-student-demand {} (first everybody)) None of my code uses contains? directly, neither does reduce, so I figure it must be one of the invocations of merge-with in my code. Here are the relevant chunks of code: ;; I can see how this would produce a LazySeq of hash-maps (defn prioritized-courses [needed-courses] (-> (for [course-set needed-courses :let [demand (course-demand course-set)]] (map #(assoc % :demand demand) (:courses course-set))) flatten)) ;; There are two merge-with instances here. This one is used inside the next one. (defn merge-demand [acc m] ;; I was admittedly doing something corny here, using a map as a key. (merge-with + acc {{:prefix (:prefix m) :number (:number m)} (:demand m)})) ;; Sum demand by course ;; Merging again here: (defn merge-student-demand [acc student] (merge-with merge-demand acc {(:id student) (prioritized-courses (:needed-courses student))})) (reduce merge-student-demand everybody) => IllegalArgumentException contains? not supported on type:clojure.lang.LazySeq clojure.lang.RT.contains (RT.java:814) I figure it's likely the Clojure core (1.8.0) merge-with function, being the first instance of contains? I could find: text-mining.core=> (source merge-with) (defn merge-with "Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter)." {:added "1.0" :static true} [f & maps] (when (some identity maps) (let [merge-entry (fn [m e] (let [k (key e) v (val e)] (if (contains? m k) ;; contains? invoked here (assoc m k (f (get m k) v)) (assoc m k v)))) merge2 (fn [m1 m2] (reduce1 merge-entry (or m1 {}) (seq m2)))] (reduce1 merge2 maps)))) Well that's my mystery. I should get around to fiddling and seeing if I can reproduce this with a more straighforward program. Best, Nathan -- 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.