Copyright © 2003-2005, Peter Seibel

18. A Few FORMAT Recipes

Common Lisp’s **FORMAT** function is—along with the extended **LOOP** macro—one of the two Common Lisp features that inspires a strong emotional response in a lot of Common Lisp users. Some love it; others hate it.1

**FORMAT**‘s fans love it for its great power and concision, while its detractors hate it because of the potential for misuse and its opacity. Complex **FORMAT** control strings sometimes bear a suspicious resemblance to line noise, but **FORMAT** remains popular with Common Lispers who like to be able to generate little bits of human-readable output without having to clutter their code with lots of output-generating code. While **FORMAT**‘s control strings can be cryptic, at least a single **FORMAT** expression doesn’t clutter things up too badly. For instance, suppose you want to print the values in a list delimited with commas. You could write this:

  1. (loop for cons on list
  2. do (format t "~a" (car cons))
  3. when (cdr cons) do (format t ", "))

That’s not too bad, but anyone reading this code has to mentally parse it just to figure out that all it’s doing is printing the contents of list to standard output. On the other hand, you can tell at a glance that the following expression is printing list, in some form, to standard output:

  1. (format t "~{~a~^, ~}" list)

If you care exactly what form the output will take, then you’ll have to examine the control string, but if all you want is a first-order approximation of what this line of code is doing, that’s immediately available.

At any rate, you should have at least a reading knowledge of **FORMAT**, and it’s worth getting a sense of what it can do before you affiliate yourself with the pro- or anti-**FORMAT** camp. It’s also important to understand at least the basics of **FORMAT** because other standard functions, such as the condition-signaling functions discussed in the next chapter, use **FORMAT**-style control strings to generate output.

To further complicate matters, **FORMAT** supports three quite different kinds of formatting: printing tables of data, pretty-printing s-expressions, and generating human-readable messages with interpolated values. Printing tables of data as text is a bit pass� these days; it’s one of those reminders that Lisp is nearly as old as FORTRAN. In fact, several of the directives you can use to print floating-point values in fixed-width fields were based quite directly on FORTRAN edit descriptors, which are used in FORTRAN to read and print columns of data arranged in fixed-width fields. However, using Common Lisp as a FORTRAN replacement is beyond the scope of this book, so I won’t discuss those aspects of **FORMAT**.

Pretty-printing is likewise beyond the scope of this book—not because it’s pass� but just because it’s too big a topic. Briefly, the Common Lisp pretty printer is a customizable system for printing block-structured data such as—but not limited to—s-expressions while varying indentation and dynamically adding line breaks as needed. It’s a great thing when you need it, but it’s not often needed in day-to-day programming.2

Instead, I’ll focus on the parts of **FORMAT** you can use to generate human-readable strings with interpolated values. Even limiting the scope in that way, there’s still a fair bit to cover. You shouldn’t feel obliged to remember every detail described in this chapter. You can get quite far with just a few **FORMAT** idioms. I’ll describe the most important features of **FORMAT** first; it’s up to you how much of a **FORMAT** wizard you want to become.