In Which I Realize that Naming is Even Harder

I was just lying in bed reading when I had a small realization related to my last post, No, Seriously, It’s Naming1: my names are wrong–but maybe not how you’d expect.

If you recall, I left things like this:

(defn anagrams-for [word candidates]
  (let [normalized-word (sort word)]
    (filter #(and (= (sort %) normalized-word)
                  (not= % word))

A basic Clojure function to find anagrams, invocable like so:

> (anagrams-for "army" ["army" "mary" "john"])

…but I started thinking, what is the interface? I mean, String provides a bunch of capabilities we don’t really need, so what do we really need? …and then it hit me:

> (anagrams-for [1 2 3] [[1 2 3] [3 2 1] [1]])
([3 2 1])

Because all we really need are some sortable-sequences. And what is a String but a sequence of characters?

So happy

In other words, we actually solved problems we didn’t even set out to solve. Useful ones even! So the names of the variables (e.g. word) may actually be too specific.

Fun fact: it can even work on an infinite sequence of candidates2:

> (let [inf (cycle [[3 2 1] [] [2 1 3]])]
>    (take 5 (anagrams-for [1 2 3] inf)))
([3 2 1] [2 1 3] [3 2 1] [2 1 3] [3 2 1])

…which may seem completely bonkers, except there are some concievable situations (time-bounded search strategies, property-based testing, etc.) where we might want to use something like this.

Anyway, I’m not going to beat you over the head with what this “all means” (you can draw your own conclusions), but do understand that this serendipity is not pure accident, but rather a consequence of the Clojure design philosophy.

And here’s Alan J. Perlis with the appeal to authority:

It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures.

  1. Which, incidentally, has turned out to be the most popular thing ever published on this blog with 5,000 hits in one day. ↩︎

  2. Note that I’m using take to only take 5 elements from the infinite list…otherwise it’ll run forever if someone pastes to their REPL. ↩︎