Irregular indentation reflects semantic structure

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.

1 comment:

1. Honestly, I think that a polynomial macro is the Right Thing here, not necessarily written by the author of the code in question.

But 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.

It's OK to comment on old posts.