read me

Clojure Golf episode 1

Aug 14, 2009

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:

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

Related posts:

  1. Clojure Golf – Episode 2: Largest Prime Factor In the last episode of Clojure Golf we saw some...
  2. Comparing Lines of Code: Scala and Clojure (FUD version) A completely tongue in cheek comparison between Scala and Clojure,...
  3. Clojure’s :pre and :post One of the more exciting features of the upcoming Clojure...
  4. Understanding the Clojure -> macro On page 109 of Paul Graham’s ANSI Common Lisp he...
  5. De-chunkifying Sequences in Clojure At the first CAP CLUG meetup I gave a presentation...

Related posts brought to you by Yet Another Related Posts Plugin.

3 Comments, Comment or Ping

  1. Well iv made another solution (http://snipplr.com/view/18345/my-filter-collection-solution/)

    My comments on the original solution:

    • Using multiple if forms feels a bit clunky to me (& not so functional).
    • The single function makes it a little harder to follow.
    • The need to reverse the result feels a bit awkward.

    Thanks for the challenge!

  2. It’s a pretty simple function.

    http://gist.github.com/169171

  3. @Ronen,

    Thanks for the snippet(s). I tend to like your second solution the best for the same reason that I like Grand’s — it tells the story of its functionality. The next step would be to lose your heads. ;) I agree with all of your comments and it goes to show that although Clojure can quite easily be translated directly from Scheme, that approach is not likely to yield idiomatic results.

    -m

Reply to “Clojure Golf episode 1”

Additional comments powered by BackType