There are well-known rules for indenting Lisp code, but it's sometimes convenient to break the rules when the code has semantic structure not reflected in the S-expressions. This sometimes happens when there are alternating sequences, as in some versions of let
and cond
and setf
. It's also common to leave forms unindented when they're supposed to be top-level but something has been wrapped around them anyway, such as eval-when
, or the library
or unit
forms required in some Scheme module systems. In either case, the indentation reflects the structure a human reader understands the program by, rather than the structure of its S-expressions.
JRM recently posted a particularly extreme example of irregular indentation:
(define (polynomial-erf z)
;; Numerical Recipies 6.2
;; fractional error < 1.2e-7
(let* ((t (/ 1.0 (+ 1.0 (* .5 (abs z)))))
(ans (- 1.0 (* t
(exp (+ (- (* z z))
(+ -1.26551223
(* t (+ 1.00002368
(* t (+ .37409196
(* t (+ .09678418
(* t (+ -.18628806
(* t (+ .27886807
(* t (+ -1.13520398
(* t (+ 1.48851587
(* t (+ -.82215223
(* t .17087277))))))))))))))))))))))))
(if (>= z 0) ans (- ans))))
Note the big polynomial written in sequential multiply-and-add style. It has two semantic structures: it's a tree of arithmetic expressions, but it's also a sequence of polynomial terms. The latter interpretation is more useful, and the indentation reflects this: it's intended to be read as a sequence, so it's indented as a sequence. If it were indented normally, according to its tree structure, its semantic sequentiality would be less obvious, not to mention it would be impractically wide:
(+ -1.26551223
(* t (+ 1.00002368
(* t (+ .37409196
(* t (+ .09678418
(* t (+ -.18628806
(* t (+ .27886807
(* t (+ -1.13520398
(* t (+ 1.48851587
(* t (+ -.82215223
(* t .17087277))))))))))))))))))
Either way, that's an imposing pile of right-parens. (You could avoid this with a simple polynomial
function or macro, but it's not worth the trouble for one polynomial.)
One of the reasons expression-based languages are so convenient is that their program structure reflects the semantic structure humans understand them by. Irregular indentation is a reminder that they don't always do so perfectly.
Honestly, I think that a polynomial macro is the Right Thing here, not necessarily written by the author of the code in question.
ReplyDeleteBut then as much as I love fully-featured standard libraries, the call of "minimalism" still resonates with me as a worthy goal... even if perhaps it shouldn't as much as it does.