Search code examples
clojure

ArityException when calling count for lazy sequence


I have written the following function for determining if two strings differ by exactly differing-char-no character positions.

(defn differ-by
    [id1 id2 differing-char-no]
    (let [zipped-ids (map vector (seq id1) (seq id2))
          differing-char-positions (filter #(not= %1 %2) zipped-ids)]
        (= differing-char-no (count differing-char-positions))))

The function, however, produces an ArityException when called. The exception is from the count function call, and says Wrong number of args (1) passed to: ....

By debugging the code I observed that both differing-char-positions and zipped-ids are lazy sequences which have not been realized. However, evaluating (count zipped-ids) works fine right away, but (count differring-char-positions) only works after having called (count zipped-ids) once, i.e. after zipped-ids has been realized. Could someone explain this behaviour? Why do these lazy sequences behave differently?


Solution

  • zipped-ids produces a sequence of vectors, so the filter function must accept a single parameter:

    (filter (fn [[a b]] (not= a b)) (map vector (seq [1 2 3]) (seq '(:a :b :c))))

    But there is a better way:

    (filter (partial apply not=) (map vector (seq [1 2 3]) (seq '(1 :b :c))))