~D
directive used to output integers in decimal emits the number with commas separating every three digits, while the at-sign modifier causes ~D
to include a plus sign when the number is positive.
CL-USER> (format t '~d' 1000000)
1000000
NIL
CL-USER> (format t '~:d' 1000000)
1,000,000
NIL
CL-USER> (format t '~@d' 1000000)
+1000000
NIL
When it makes sense, you can combine the colon and at-sign modifiers to get both modifications.
CL-USER> (format t '~:@d' 1000000)
+1,000,000
NIL
In directives where the two modified behaviors can't be meaningfully combined, using both modifiers is either undefined or given a third meaning.
Now you're ready to look at specific directives. I'll start with several of the most commonly used directives, including some you've seen in previous chapters.
The most general-purpose directive is ~A
, which consumes one format argument of any type and outputs it in
(format nil 'The value is: ~a' 10) ==> 'The value is: 10'
(format nil 'The value is: ~a' 'foo') ==> 'The value is: foo'
(format nil 'The value is: ~a' (list 1 2 3)) ==> 'The value is: (1 2 3)'
A closely related directive, ~S
, likewise consumes one format argument of any type and outputs it. However, ~S
tries to generate output that can be read back in with READ
. Thus, strings will be enclosed in quotation marks, symbols will be package-qualified when necessary, and so on. Objects that don't have a READ
able representation are printed with the unreadable object syntax, #<>
. With a colon modifier, both the ~A
and ~S
directives emit NIL
as ()
rather than NIL
. Both the ~A
and ~S
directives also take up to four prefix parameters, which can be used to control whether padding is added after (or before with the at- sign modifier) the value, but those parameters are only really useful for generating tabular data.
The other two most frequently used directives are ~%
, which emits a newline, and ~&
, which emits a ~%
always emits a newline, while ~&
emits one only if it's not already at the beginning of a line. This is handy when writing loosely coupled functions that each generate a piece of output and that need to be combined in different ways. For instance, if one function generates output that ends with a newline (~%
) and another function generates some output that starts with a fresh line (~&
), you don't have to worry about getting an extra blank line if you call them one after the other. Both of these directives can take a single prefix parameter that specifies the number of newlines to emit. The ~%
directive will simply emit that many newline characters, while the ~&
directive will emit either
Less frequently used is the related ~~
directive, which causes FORMAT
to emit a literal tilde. Like the ~%
and ~&
directives, it can be parameterized with a number that controls how many tildes to emit.
In addition to the general-purpose directives, ~A
and ~S
, FORMAT
supports several directives that can be used to emit values of specific types in particular ways. One of the simplest of these is the ~C
directive, which is used to emit characters. It takes no prefix arguments but can be modified with the colon and at-sign modifiers. Unmodified, its behavior is no different from ~A
except that it works only with characters. The modified versions are more useful. With a colon modifier, ~:C
outputs
(format t 'Syntax error. Unexpected character: ~:c' char)
can emit messages like this:
Syntax error. Unexpected character: a
but also like the following:
Syntax error. Unexpected character: Space
With the at-sign modifier, ~@C
will emit the character in Lisp's literal character syntax.
CL-USER> (format t '~@c~%' #a)
#a
NIL
With both the colon and at-sign modifiers, the ~C
directive can print extra information about how to enter the character at the keyboard if it requires special key combinations. For instance, on the Macintosh, in certain applications you can enter a null character (character code 0 in ASCII or in any ASCII superset such as ISO-8859-1 or Unicode) by pressing the Control key and typing @. In OpenMCL, if you print the null character with the ~:C
directive, it tells you this:
(format nil '~:@c' (code-char 0)) ==> '^@ (Control @)'
However, not all Lisps implement this aspect of the ~C
directive. And even if they do, it may or may not be accurate—for instance, if you're running OpenMCL in SLIME, the C-@
key chord is intercepted by Emacs, invoking set-mark-command
.[196]
Format directives dedicated to emitting numbers are another important category. While you can use the ~A
and ~S
directives to emit numbers, if you want fine control over how they're printed, you need to use one of the number-specific directives. The numeric directives can be divided into two subcategories: directives for formatting integer values and directives for formatting floating-point values.
Five closely related directives format integer values: ~D
, ~X
, ~O
, ~B
, and ~R
. The most frequently used is the ~D
directive, which outputs integers in base 10.
(format nil '~d' 1000000) ==> '1000000'