Skip to content

Commit da8470b

Browse files
committed
Add lots of rationale on "semantic" vs "fixed" indentation
1 parent 6ae13d4 commit da8470b

File tree

1 file changed

+104
-1
lines changed

1 file changed

+104
-1
lines changed

README.adoc

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,13 @@ Vertically align function (macro) arguments spanning multiple lines.
232232
(range 1 10))
233233
----
234234

235-
=== Arguments Indentation [[one-space-indent]]
235+
The reasoning behind this guideline is pretty simple - the arguments are
236+
easier to process by the human brain if they stand out and stick together.
237+
238+
=== Function Arguments Indentation [[one-space-indent]]
239+
240+
NOTE: Generally, you should stick to the formatting outlined in the previous
241+
guideline, unless you're limited by the available horizonal space.
236242

237243
Use a single space indentation for function (macro) arguments
238244
when there are no arguments on the same line as the function name.
@@ -260,6 +266,103 @@ when there are no arguments on the same line as the function name.
260266
portokala)
261267
----
262268

269+
This may appear like some weird special rule to people without Lisp background, but the
270+
reasoning behind it is quite simple. Function calls are
271+
nothing but regular list literals and normally those are aligned in the same way as
272+
other collection type literals when spanning multiple lines:
273+
274+
[source,clojure]
275+
----
276+
;; list literal
277+
(1
278+
2
279+
3)
280+
281+
;; vector literal
282+
[1
283+
2
284+
3]
285+
286+
;; set literal
287+
#{1
288+
2
289+
3}
290+
----
291+
292+
Admittedly, list literals are not very common in Clojure, that's why it's understandable
293+
that for many people lists are nothing but an invocation syntax.
294+
295+
As a side benefit, function arguments are still aligned in this scenario as well. They
296+
just happen to accidentally be aligned with the function name as well.
297+
298+
.Semantic Indentation vs Fixed Indentation
299+
****
300+
The guidelines to indent differently macros with body forms from
301+
all other macro and function calls are collectively known as
302+
"semantic indentation". Simply put, this means that the code
303+
is indented differently, so that the indentation would give the
304+
reader of the code some hints about its meaning.
305+
306+
The downside of this approach is that requires Clojure code formatters to be
307+
smarter. They either need to process `macro` arglists and rely on the fact
308+
that people named their parameters consistently, or process some additional
309+
indentation metadata.
310+
311+
Some people in the Clojure community have argued that's not worth it and
312+
that everything should simply be indented in the same fashion. Here are
313+
a few examples:
314+
315+
[source,clojure]
316+
----
317+
;;; Fixed Indentation
318+
;;
319+
;; macros
320+
(when something
321+
(something-else))
322+
323+
(with-out-str
324+
(println "Hello, ")
325+
(println "world!"))
326+
327+
;; function call spanning two lines
328+
(filter even?
329+
(range 1 10))
330+
331+
;; function call spanning three lines
332+
(filter
333+
even?
334+
(range 1 10))
335+
----
336+
337+
This suggestion has certainly gotten some ground in the community, but it also
338+
goes against the entire Lisp tradition and the primary goal of this style guide -
339+
namely to optimize code for human consumption.
340+
341+
There's also one small caveat with fixed indentation that's rarely discussed and that's
342+
how to indent list literals, as function calls are simply list literals. As those
343+
are not very common in Clojure, outside the context of providing structure for the Clojure
344+
code itself, that matter is usually omitted from consideration:
345+
346+
[source,clojure]
347+
----
348+
;;; Fixed Indentation
349+
;;
350+
;; list literals
351+
(1 2 3
352+
4 5 6)
353+
354+
(1
355+
2
356+
3
357+
4
358+
5
359+
6)
360+
----
361+
362+
That looks a bit weird and happens to be inconsistent with how other collection types are normally indented.
363+
364+
****
365+
263366
=== Bindings Alignment [[bindings-alignment]]
264367

265368
Vertically align `let` (and `let`-like) bindings.

0 commit comments

Comments
 (0)