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".