exupero's blog
RSSApps

Clojure indentation commas

I read the blog post "Clojure indentation commas" a couple years ago and liked the idea enough to start using it regularly. I use it most in let and cond.

I almost never give lengthy names to let bindings, but destructuring can make the left side of a binding too long to comfortably put a form after. In those cases I use an indentation comma to make the right-hand expression more apparent:

(let [{:keys [verticals horizontals] :as grid}
      , (create-grid {:width 400
                      :height 400
                      :rows 20
                      :columns 20})]
  ...)

I do that occasionally in throwaway code I write, but more often on this blog, where I want to keep the width of any code narrow enough to avoid horizontal scrolling.

In cond, I use indentation commas as a substitute for blank lines between predicate/expression pairs. I tend not to use blank lines within the body of a function, but cond has always been the place that tempted me to add them. Predicates in cond can get somewhat wide, and moving expressions to the line after their predicate creates a flat, left-aligned sequence of forms where it can be hard to track which forms are the predicates and which are the result clauses. Indentation commas create a pleasing third option:

(cond
  (nil? form)
  , pairs
  (prop? form)
  , (recur forms form pairs)
  :else
  , (recur forms '.child (conj pairs [form prop])))

As with let, indentation commas in cond help keep the code narrower in constricted settings like this blog.

While plain, comma-less indentation could achieve these same effects, the leading comma creates a kind of bullet-point notation that adds visual structure without changing the structure of the code. The leading commas show intention where some might just see sloppy spacing. Also, if you're using Parinfer, an indentation comma prevents Parifer from putting the indented code inside the form above it.