Next: , Previous: Output Procedures, Up: Input/Output


14.6 Format

The procedure format is very useful for producing nicely formatted text, producing good-looking messages, and so on. MIT/GNU Scheme's implementation of format is similar to that of Common Lisp, except that Common Lisp defines many more directives.1

format is a run-time-loadable option. To use it, execute

     (load-option 'format)

once before calling it.

— procedure: format destination control-string argument ...

Writes the characters of control-string to destination, except that a tilde (~) introduces a format directive. The character after the tilde, possibly preceded by prefix parameters and modifiers, specifies what kind of formatting is desired. Most directives use one or more arguments to create their output; the typical directive puts the next argument into the output, formatted in some special way. It is an error if no argument remains for a directive requiring an argument, but it is not an error if one or more arguments remain unprocessed by a directive.

The output is sent to destination. If destination is #f, a string is created that contains the output; this string is returned as the value of the call to format. In all other cases format returns an unspecified value. If destination is #t, the output is sent to the current output port. Otherwise, destination must be an output port, and the output is sent there.

This procedure performs discretionary output flushing (see Output Procedures).

A format directive consists of a tilde (~), optional prefix parameters separated by commas, optional colon (:) and at-sign (@) modifiers, and a single character indicating what kind of directive this is. The alphabetic case of the directive character is ignored. The prefix parameters are generally integers, notated as optionally signed decimal numbers. If both the colon and at-sign modifiers are given, they may appear in either order.

In place of a prefix parameter to a directive, you can put the letter `V' (or `v'), which takes an argument for use as a parameter to the directive. Normally this should be an exact integer. This feature allows variable-width fields and the like. You can also use the character `#' in place of a parameter; it represents the number of arguments remaining to be processed.

It is an error to give a format directive more parameters than it is described here as accepting. It is also an error to give colon or at-sign modifiers to a directive in a combination not specifically described here as being meaningful.

~A
The next argument, which may be any object, is printed as if by display. ~mincolA inserts spaces on the right, if necessary, to make the width at least mincol columns. The @ modifier causes the spaces to be inserted on the left rather than the right.
~S
The next argument, which may be any object, is printed as if by write. ~mincolS inserts spaces on the right, if necessary, to make the width at least mincol columns. The @ modifier causes the spaces to be inserted on the left rather than the right.
~%
This outputs a #\newline character. ~n% outputs n newlines. No argument is used. Simply putting a newline in control-string would work, but ~% is often used because it makes the control string look nicer in the middle of a program.
~~
This outputs a tilde. ~n~ outputs n tildes.
~newline
Tilde immediately followed by a newline ignores the newline and any following non-newline whitespace characters. With an @, the newline is left in place, but any following whitespace is ignored. This directive is typically used when control-string is too long to fit nicely into one line of the program:
               (define (type-clash-error procedure arg spec actual)
                 (format
                  #t
                  "~%Procedure ~S~%requires its %A argument ~
                   to be of type ~S,~%but it was called with ~
                   an argument of type ~S.~%"
                  procedure arg spec actual))
          
               (type-clash-error 'vector-ref
                                 "first"
                                 'integer
                                 'vector)
               
               prints
               
               Procedure vector-ref
               requires its first argument to be of type integer,
               but it was called with an argument of type vector.
          

Note that in this example newlines appear in the output only as specified by the ~% directives; the actual newline characters in the control string are suppressed because each is preceded by a tilde.


Footnotes

[1] This description of format is adapted from Common Lisp, The Language, second edition, section 22.3.3.