Formatting Lisp Code

While code formatting is, strictly speaking, neither a syntactic nor a semantic matter, proper formatting is important to reading and writing code fluently and idiomatically. The key to formatting Lisp code is to indent it properly. The indentation should reflect the structure of the code so that you don’t need to count parentheses to see what goes with what. In general, each new level of nesting gets indented a bit more, and, if line breaks are necessary, items at the same level of nesting are lined up. Thus, a function call that needs to be broken up across multiple lines might be written like this:

  1. (some-function arg-with-a-long-name
  2. another-arg-with-an-even-longer-name)

Macro and special forms that implement control constructs are typically indented a little differently: the “body” elements are indented two spaces relative to the opening parenthesis of the form. Thus:

  1. (defun print-list (list)
  2. (dolist (i list)
  3. (format t "item: ~a~%" i)))

However, you don’t need to worry too much about these rules because a proper Lisp environment such as SLIME will take care of it for you. In fact, one of the advantages of Lisp’s regular syntax is that it’s fairly easy for software such as editors to know how to indent it. Since the indentation is supposed to reflect the structure of the code and the structure is marked by parentheses, it’s easy to let the editor indent your code for you.

In SLIME, hitting Tab at the beginning of each line will cause it to be indented appropriately, or you can re-indent a whole expression by positioning the cursor on the opening parenthesis and typing C-M-q. Or you can re-indent the whole body of a function from anywhere within it by typing C-c M-q.

Indeed, experienced Lisp programmers tend to rely on their editor handling indenting automatically, not just to make their code look nice but to detect typos: once you get used to how code is supposed to be indented, a misplaced parenthesis will be instantly recognizable by the weird indentation your editor gives you. For example, suppose you were writing a function that was supposed to look like this:

  1. (defun foo ()
  2. (if (test)
  3. (do-one-thing)
  4. (do-another-thing)))

Now suppose you accidentally left off the closing parenthesis after test. Because you don’t bother counting parentheses, you quite likely would have added an extra parenthesis at the end of the **DEFUN** form, giving you this code:

  1. (defun foo ()
  2. (if (test
  3. (do-one-thing)
  4. (do-another-thing))))

However, if you had been indenting by hitting Tab at the beginning of each line, you wouldn’t have code like that. Instead you’d have this:

  1. (defun foo ()
  2. (if (test
  3. (do-one-thing)
  4. (do-another-thing))))

Seeing the then and else clauses indented way out under the condition rather than just indented slightly relative to the **IF** shows you immediately that something is awry.

Another important formatting rule is that closing parentheses are always put on the same line as the last element of the list they’re closing. That is, don’t write this:

  1. (defun foo ()
  2. (dotimes (i 10)
  3. (format t "~d. hello~%" i)
  4. )
  5. )

but instead write this:

  1. (defun foo ()
  2. (dotimes (i 10)
  3. (format t "~d. hello~%" i)))

The string of )))s at the end may seem forbidding, but as long your code is properly indented the parentheses should fade away—no need to give them undue prominence by spreading them across several lines.

Finally, comments should be prefaced with one to four semicolons depending on the scope of the comment as follows:

  1. ;;;; Four semicolons are used for a file header comment.
  2. ;;; A comment with three semicolons will usually be a paragraph
  3. ;;; comment that applies to a large section of code that follows,
  4. (defun foo (x)
  5. (dotimes (i x)
  6. ;; Two semicolons indicate this comment applies to the code
  7. ;; that follows. Note that this comment is indented the same
  8. ;; as the code that follows.
  9. (some-function-call)
  10. (another i) ; this comment applies to this line only
  11. (and-another) ; and this is for this line
  12. (baz)))

Now you’re ready to start looking in greater detail at the major building blocks of Lisp programs, functions, variables, and macros. Up next: functions.


1http://www-formal.stanford.edu/jmc/history/lisp/node3.html

2Lisp implementers, like implementers of any language, have many ways they can implement an evaluator, ranging from a “pure” interpreter that interprets the objects given to the evaluator directly to a compiler that translates the objects into machine code that it then runs. In the middle are implementations that compile the input into an intermediate form such as bytecodes for a virtual machine and then interprets the bytecodes. Most Common Lisp implementations these days use some form of compilation even when evaluating code at run time.

3Sometimes the phrase s-expression refers to the textual representation and sometimes to the objects that result from reading the textual representation. Usually either it’s clear from context which is meant or the distinction isn’t that important.

4Not all Lisp objects can be written out in a way that can be read back in. But anything you can **READ** can be printed back out “readably” with **PRINT**.

5The empty list, (), which can also be written **NIL**, is both an atom and a list.

6In fact, as you’ll see later, names aren’t intrinsically tied to any one kind of thing. You can use the same name, depending on context, to refer to both a variable and a function, not to mention several other possibilities.

7The case-converting behavior of the reader can, in fact, be customized, but understanding when and how to change it requires a much deeper discussion of the relation between names, symbols, and other program elements than I’m ready to get into just yet.

8I’ll discuss the relation between symbols and packages in more detail in Chapter 21.

9Of course, other levels of correctness exist in Lisp, as in other languages. For instance, the s-expression that results from reading (foo 1 2) is syntactically well-formed but can be evaluated only if foo is the name of a function or macro.

10One other rarely used kind of Lisp form is a list whose first element is a lambda form. I’ll discuss this kind of form in Chapter 5.

11One other possibility exists—it’s possible to define symbol macros that are evaluated slightly differently. We won’t worry about them.

12In Common Lisp a symbol can name both an operator—function, macro, or special operator—and a variable. This is one of the major differences between Common Lisp and Scheme. The difference is sometimes described as Common Lisp being a Lisp-2 vs. Scheme being a Lisp-1—a Lisp-2 has two namespaces, one for operators and one for variables, but a Lisp-1 uses a single namespace. Both choices have advantages, and partisans can debate endlessly which is better.

13The others provide useful, but somewhat esoteric, features. I’ll discuss them as the features they support come up.

14Well, one difference exists—literal objects such as quoted lists, but also including double-quoted strings, literal arrays, and vectors (whose syntax you’ll see later), must not be modified. Consequently, any lists you plan to manipulate you should create with **LIST**.

15This syntax is an example of a reader macro. Reader macros modify the syntax the reader uses to translate text into Lisp objects. It is, in fact, possible to define your own reader macros, but that’s a rarely used facility of the language. When most Lispers talk about “extending the syntax” of the language, they’re talking about regular macros, as I’ll discuss in a moment.

16People without experience using Lisp’s macros or, worse yet, bearing the scars of C preprocessor-inflicted wounds, tend to get nervous when they realize that macro calls look like regular function calls. This turns out not to be a problem in practice for several reasons. One is that macro forms are usually formatted differently than function calls. For instance, you write the following:

  1. (dolist (x foo)
  2. (print x))

rather than this:

  1. (dolist (x foo) (print x))

or

  1. (dolist (x foo)
  2. (print x))

the way you would if **DOLIST** was a function. A good Lisp environment will automatically format macro calls correctly, even for user-defined macros.

And even if a **DOLIST** form was written on a single line, there are several clues that it’s a macro: For one, the expression (x foo) is meaningful by itself only if x is the name of a function or macro. Combine that with the later occurrence of x as a variable, and it’s pretty suggestive that **DOLIST** is a macro that’s creating a binding for a variable named x. Naming conventions also help—looping constructs, which are invariably macros—are frequently given names starting with do.

17Using the empty list as false is a reflection of Lisp’s heritage as a list-processing language much as the use of the integer 0 as false in C is a reflection of its heritage as a bit-twiddling language. Not all Lisps handle boolean values the same way. Another of the many subtle differences upon which a good Common Lisp vs. Scheme flame war can rage for days is Scheme’s use of a distinct false value #f, which isn’t the same value as either the symbol nil or the empty list, which are also distinct from each other.

18Even the language standard is a bit ambivalent about which of **EQ** or **EQL** should be preferred. Object identity is defined by **EQ**, but the standard defines the phrase the same when talking about objects to mean **EQL** unless another predicate is explicitly mentioned. Thus, if you want to be 100 percent technically correct, you can say that (- 3 2) and (- 4 3) evaluate to “the same” object but not that they evaluate to “identical” objects. This is, admittedly, a bit of an angels-on-pinheads kind of issue.