The FORMAT Function

As you’ve seen in previous chapters, the **FORMAT** function takes two required arguments: a destination for its output and a control string that contains literal text and embedded directives. Any additional arguments provide the values used by the directives in the control string that interpolate values into the output. I’ll refer to these arguments as format arguments.

The first argument to **FORMAT**, the destination for the output, can be **T**, **NIL**, a stream, or a string with a fill pointer. **T** is shorthand for the stream ***STANDARD-OUTPUT***, while **NIL** causes **FORMAT** to generate its output to a string, which it then returns.3 If the destination is a stream, the output is written to the stream. And if the destination is a string with a fill pointer, the formatted output is added to the end of the string and the fill pointer is adjusted appropriately. Except when the destination is **NIL** and it returns a string, **FORMAT** returns **NIL**.

The second argument, the control string, is, in essence, a program in the **FORMAT** language. The **FORMAT** language isn’t Lispy at all—its basic syntax is based on characters, not s-expressions, and it’s optimized for compactness rather than easy comprehension. This is why a complex **FORMAT** control string can end up looking like line noise.

Most of **FORMAT**‘s directives simply interpolate an argument into the output in one form or another. Some directives, such as ~%, which causes **FORMAT** to emit a newline, don’t consume any arguments. And others, as you’ll see, can consume more than one argument. One directive even allows you to jump around in the list of arguments in order to process the same argument more than once or to skip certain arguments in certain situations. But before I discuss specific directives, let’s look at the general syntax of a directive.