Here’s a piece of somewhat–ugly, single–purpose Python code, what it does is not particularly interesting:
def span(data): r =  for row in data: if r and row == r[-1]: r[-1] = row else: r.append([row, row, row]) return r
After a couple of days of wondering how this might be done in Clojure, I stumbled upon the idea of a partition, and went looking in the docs. Here’s the Clojure version:
(defn span [data] (map (fn [spn] [(first (first spn)) (first (last spn)) (second (first spn))]) (partition-by (fn [row] (second row)) data)))
To my eye, the Clojure version is a lot nicer (although it could be novelty, or the square brackets containing “magic numbers” in the Python version).
The beauty of the Clojure version comes from the partition-by function, replicated below:
(defn partition-by [f coll] (lazy-seq (when-let [s (seq coll)] (let [fst (first s) fv (f fst) run (cons fst (take-while #(= fv (f %)) (next s)))] (cons run (partition-by f (seq (drop (count run) s))))))))
After a few minutes of working out what it does, it “popped”, and at the same time I had a break–through in my understanding of functional programming.
For completeness, here’s a version of partition-by in Python:
import itertools def partition_by(f, coll): if not coll: return  head, tail = coll, coll[1:] run = [head] + list(itertools.takewhile(lambda t: f(t) == f(head), tail)) return [run] + func_partition_by(f, coll[len(run):])
Which can be used to refactor the original span function to:
def span(data): return map( lambda r: [r, r[-1], r], partition_by(lambda row: row, data))
The nice thing about the original Clojure version, and the final Python version is that the format of the “rows”, and the logic for partitioning data are separate: something I wouldn’t have done if it weren’t for my recent interest in Clojure.