I made a silly assumption the first time I implemented John Conway's "Game of Life" in clojure. Here's what my high-level
evolve function looked like:
(defn evolve [grid] (let [neighbors (mapcat neighbors-of grid) in-play (set/union grid neighbors) updated (map #(update-cell % grid) in-play)] (set (remove nil? updated))))
It passed all tests and didn't look too bad. At 198 characters I was actually quite proud of it. Here's the version I came up with today:
(defn evolve [grid] (->> (mapcat neighbors-of grid) (map #(update-cell % grid)) (remove nil?) set))
This version is just over half as many characters as the last one, partly because I dispensed with the let statment in favor of a threading macro. But it's also one step shorter--the
set/union call is absent now, because it's actually not needed. When I first removed (and saw that the tests were still passing!) it I wondered if my test suite was incomplete. But after a bit of thought (and seeing the GUI still work flawlessly) I became convined that it simply wasn't needed.
Maybe this is a good example of what Oliver Wendell Holmes was talking about when he coined the phrase "simplicity on the other side of complexity".