Clojure Don’ts: Redundant map

Today’s Clojure Don’t is the opposite side of the coin to the heisenparameter.

If you have an operation on a single object, you don’t need to define another version just to operate on a collection of those objects.

That is, if you have a function like this:

(defn process-thing [thing]
  ;; process one thing
  )

There is no reason to also write this:

(defn process-many-things [things]
  (map process-thing things))

The idiom “map a function over a collection” is so universal that any Clojure programmer should be able to write it without thinking twice.

Having a separate definition for processing a group of things implies that there is something special about processing a group instead of a single item. (For example, a more efficient batch implementation.) If that’s the case, then by all means write the batch version as well. But if not, then a function like process-many-things just clutters up your code while providing no benefit.

4 Replies to “Clojure Don’ts: Redundant map”

  1. I’d take this one step further and say that, absent the motivation you described (something special about this particular batch job), even when you only have a process-many-things fn (and do not have a process-thing fn), it is preferable to convert the process-many-things fn to a process-thing fn and update the call sites to use map. It makes things more flexible as requirements and code evolves, and nudges a codebase toward consistency. WDYT?

  2. I like the idea but kind of disconcur with the elaboration. A proliferation of one-at-a-time functions is an invitation to the old n+1 selects problem. Better to force your consumers to use functions that operate on sequences from the outset if you suspect that you’ll ever want to implement some form of batching behaviour.

    Awesome blog though, thank you!

  3. Yes! I agree whole heartedly. I also never write maps-over-many-things fns unless they need shared context (not the norm)

Comments are closed.