This is an attempt to have some fun with Clojure. I hope to engage the Clojure community, but it would be all the more fun if others played along with their chosen language(s). The idea is that I present a sub-optimal code snippet and people throw in their optimized, smallest, and/or weirdest submissions of that same function.

Episode 1 is the function filter-collecting taken directly from Greg’s Little Object System – the code is thus:

(defn filter-collecting [predicate collector & lists] 
  (lazy-seq 
    (loop [lists lists out []] 
      (if (empty? (first lists)) 
        (reverse out) 
        (let [heads (map first lists)] 
          (if (apply predicate heads) 
            (recur (map rest lists) (cons (apply collector heads) out)) 
            (recur (map rest lists) out)))))))

(filter-collecting (fn [x y] (< x y)) (fn [x y] (+ x y)) ‘(1 7 3 9) ‘(5 5 5 5)) 
;;=> (6 8)

In a nutshell, it takes n number of lists and applies a predicate to subsequent elements. If said predicate passes, then it applies the collector function (arity n) and returns that result in a collection. As a starting point, it should be noted that this is a direct translation from Scheme and should be more Clojure-esque

Have fun.

Follow-up

There were some nice follow-ups on the Clojure group (code changes only done for formatting purposes):

Jarkko Oranen

(defn filter-collecting [c f & seqs] 
  (remove nil? 
          (apply map (fn [& args] 
                       (when (apply c args) 
                         (apply f args))) 
                 seqs))) 

Christophe Grand

my personal favorite
(defn filter-collecting [predicate collector & lists] 
  (for [v (apply map vector lists) 
          :when (apply predicate v)] 
    (apply collector v))) 

Chris Houser

(defn filter-collecting [p c & l] 
  (map #(apply c %) 
       (filter #(apply p %) 
               (apply map vector l)))) 

Laurent Petit

(let [x (Object.)] 
   (defn filter-collecting [p c & l] 
      (remove #(identical? % x) 
        (apply map #(if (apply p %&) (apply c %&) x) l)))) 

;; AND 

(defn filter-collecting [p c & l] 
  (apply mapcat 
         #(when (apply p %&) [(apply c %&)]) l))  

Jonathan Smith

(defn filter-collecting [p c & seqs] 
  (let [fun #(if (apply p %1) 
               (conj! %2 (apply c %1)) 
               %2)] 
    (loop [hs (map first seqs) 
           ts (map rest seqs) 
           result (transient [])] 
      (if (next (first ts)) 
        (recur (map first ts) 
               (map rest ts) 
               (fun hs result)) 
        (persistent! (fun hs result))))))

Thanks to everyone who participated.

-m