Common Lisp the Language, 2nd Edition

Next: Input Functions Up: Printed Representation of Previous: The Readtable

## 22.1.6. What the Print Function Produces

The Common Lisp printer is controlled by a number of special variables. These are referred to in the following discussion and are fully documented at the end of this section.

How an expression is printed depends on its data type, as described in the following paragraphs.

Integers
  If appropriate, a radix specifier may be printed; see the variable `*print-radix*`. If an integer is negative, a minus sign is printed and then the absolute value of the integer is printed. Integers are printed in the radix specified by the variable `*print-base*` in the usual positional notation, most significant digit first. The number zero is represented by the single digit `0` and never has a sign. A decimal point may then be printed, depending on the value of `*print-radix*`.

Ratios
  If appropriate, a radix specifier may be printed; see the variable `*print-radix*`. If the ratio is negative, a minus sign is printed. Then the absolute value of the numerator is printed, as for an integer; then a `/`; then the denominator. The numerator and denominator are both printed in the radix specified by the variable `*print-base*`; they are obtained as if by the `numerator` and `denominator` functions, and so ratios are always printed in reduced form (lowest terms).

Floating-point numbers
  If the sign of the number (as determined by the function `float-sign`) is negative, then a minus sign is printed. Then the magnitude is printed in one of two ways. If the magnitude of the floating-point number is either zero or between (inclusive) and (exclusive), it may be printed as the integer part of the number, then a decimal point, followed by the fractional part of the number; there is always at least one digit on each side of the decimal point. If the format of the number does not match that specified by the variable `*read-default-float-format*`, then the exponent marker for that format and the digit `0` are also printed. For example, the base of the natural logarithms as a short-format floating-point number might be printed as `2.71828S0`.

  For non-zero magnitudes outside of the range to , a floating-point number will be printed in ``computerized scientific notation.'' The representation of the number is scaled to be between 1 (inclusive) and 10 (exclusive) and then printed, with one digit before the decimal point and at least one digit after the decimal point. Next the exponent marker for the format is printed, except that if the format of the number matches that specified by the variable `*read-default-float-format*`, then the exponent marker `E` is used. Finally, the power of 10 by which the fraction must be multiplied to equal the original number is printed as a decimal integer. For example, Avogadro's number as a short-format floating-point number might be printed as `6.02S23`.

Complex numbers
  A complex number is printed as `#C`, an open parenthesis, the printed representation of its real part, a space, the printed representation of its imaginary part, and finally a close parenthesis.

Characters
  When `*print-escape*` is `nil`, a character prints as itself; it is sent directly to the output stream. When `*print-escape*` is not `nil`, then `#\` syntax is used. For example, the printed representation of the character `#\A` with control and meta bits on would be `#\CONTROL-META-A`, and that of `#\a` with control and meta bits on would be `#\CONTROL-META-\a`.

  X3J13 voted in June 1989 (DATA-IO) to specify that if `*print-readably*` is not `nil` then every object must be printed in a readable form, regardless of other printer control variables. For characters, the simplest approach is always to use `#\` syntax when `*print-readably*` is not `nil`, regardless of the value of `*print-escape*`.

Symbols
  When `*print-escape*` is `nil`, only the characters of the print name of the symbol are output (but the case in which to print any uppercase characters in the print name is controlled by the variable `*print-case*`).

  X3J13 voted in June 1989 (READ-CASE-SENSITIVITY) to specify that the new `readtable-case` slot of the current readtable also controls the case in which letters (whether uppercase or lowercase) in the print name of a symbol are output, no matter what the value of `*print-escape*`.

  The remaining paragraphs describing the printing of symbols cover the situation when `*print-escape*` is not `nil`.

  X3J13 voted in June 1989 (DATA-IO) to specify that if `*print-readably*` is not `nil` then every object must be printed in a readable form, regardless of other printer control variables. For symbols, the simplest approach is to print them, when `*print-readably*` is not `nil`, as if `*print-escape*` were not `nil`, regardless of the actual value of `*print-escape*`.

  Backslashes `` and vertical bars `|` are included as required. In particular, backslash or vertical-bar syntax is used when the name of the symbol would be otherwise treated by the reader as a potential number (see section 22.1.2). In making this decision, it is assumed that the value of `*print-base*` being used for printing would be used as the value of `*read-base*` used for reading; the value of `*read-base*` at the time of printing is irrelevant. For example, if the value of `*print-base*` were `16` when printing the symbol `face`, it would have to be printed as `FACE` or `Face` or `|FACE|`, because the token `face` would be read as a hexadecimal number (decimal value 64206) if `*read-base*` were `16`.

  The case in which to print any uppercase characters in the print name is controlled by the variable `*print-case*`.

  X3J13 voted in June 1989 (PRINT-CASE-PRINT-ESCAPE-INTERACTION) to clarify the interaction of `*print-case*` with `*print-escape*`; see `*print-case*`.

  As a special case [no pun intended], `nil` may sometimes be printed as `()` instead, when `*print-escape*` and `*print-pretty*` are both not `nil`.

  Package prefixes may be printed (using colon syntax) if necessary. The rules for package qualifiers are as follows. When the symbol is printed, if it is in the keyword package, then it is printed with a preceding colon; otherwise, if it is accessible in the current package, it is printed without any qualification; otherwise, it is printed with qualification. See chapter 11.

  A symbol that is uninterned (has no home package) is printed preceded by `#:` if the variables `*print-gensym*` and `*print-escape*` are both non-`nil`; if either is `nil`, then the symbol is printed without a prefix, as if it were in the current package.

  X3J13 voted in June 1989 (DATA-IO) to specify that if `*print-readably*` is not `nil` then every object must be printed in a readable form, regardless of other printer control variables. For uninterned symbols, the simplest approach is to print them, when `*print-readably*` is not `nil`, as if `*print-escape*` and `*print-gensym*` were not `nil`, regardless of their actual values.

Implementation note: Because the `#:` syntax does not intern the following symbol, it is necessary to use circular-list syntax if `*print-circle*` is not `nil` and the same uninterned symbol appears several times in an expression to be printed. For example, the result of

    (let ((x (make-symbol "FOO"))) (list x x))

would be printed as

    (#:foo #:foo)

if `*print-circle*` were `nil`, but as

    (#1=#:foo #1#)

if `*print-circle*` were not `nil`.

  The case in which symbols are to be printed is controlled by the variable `*print-case*`.

  It is also controlled by `*print-escape*` and the `readtable-case` slot of the current readtable (the value of `*readtable*`).

Strings
  The characters of the string are output in order. If `*print-escape*` is not `nil`, a double quote is output before and after, and all double quotes and single escape characters are preceded by backslash. The printing of strings is not affected by `*print-array*`. If the string has a fill pointer, then only those characters below the fill pointer are printed.

  X3J13 voted in June 1989 (DATA-IO) to specify that if `*print-readably*` is not `nil` then every object must be printed in a readable form, regardless of other printer control variables. For strings, the simplest approach is to print them, when `*print-readably*` is not `nil`, as if `*print-escape*` were not `nil`, regardless of the actual value of `*print-escape*`.

Conses
  Wherever possible, list notation is preferred over dot notation. Therefore the following algorithm is used:
  1. Print an open parenthesis, `(`.
  2. Print the car of the cons.
  3. If the cdr is a cons, make it the current cons, print a space, and go to step 2.
  4. If the cdr is not null, print a space, a dot, a space, and the cdr.
  5. Print a close parenthesis, `)`.

  This form of printing is clearer than showing each individual cons cell. Although the two expressions below are equivalent, and the reader will accept either one and produce the same data structure, the printer will always print such a data structure in the second form.

      (a . (b . ((c . (d . nil)) . (e . nil))))

      (a b (c d) e)

  The printing of conses is affected by the variables `*print-level*` and `*print-length*`.

  X3J13 voted in June 1989 (DATA-IO) to specify that if `*print-readably*` is not `nil` then every object must be printed in a readable form, regardless of other printer control variables. For conses, the simplest approach is to print them, when `*print-readably*` is not `nil`, as if `*print-level*` and `*print-length*` were `nil`, regardless of their actual values.

Bit-vectors
  A bit-vector is printed as `#*` followed by the bits of the bit-vector in order. If `*print-array*` is `nil`, however, then the bit-vector is printed in a format (using `#<`) that is concise but not readable. If the bit-vector has a fill pointer, then only those bits below the fill pointer are printed.

  X3J13 voted in June 1989 (DATA-IO) to specify that if `*print-readably*` is not `nil` then every object must be printed in a readable form, regardless of other printer control variables. For bit-vectors, the simplest approach is to print them, when `*print-readably*` is not `nil`, as if `*print-array*` were not `nil`, regardless of the actual value of `*print-array*`.

Vectors
  Any vector other than a string or bit-vector is printed using general-vector syntax; this means that information about specialized vector representations will be lost. The printed representation of a zero-length vector is `#()`. The printed representation of a non-zero-length vector begins with `#(`. Following that, the first element of the vector is printed. If there are any other elements, they are printed in turn, with a space printed before each additional element. A close parenthesis after the last element terminates the printed representation of the vector.

  The printing of vectors is affected by the variables `*print-level*` and `*print-length*`. If the vector has a fill pointer, then only those elements below the fill pointer are printed.

  If `*print-array*` is `nil`, however, then the vector is not printed as described above, but in a format (using `#<`) that is concise but not readable.

  X3J13 voted in June 1989 (DATA-IO) to specify that if `*print-readably*` is not `nil` then every object must be printed in a readable form, regardless of other printer control variables. For vectors, the simplest approach is to print them, when `*print-readably*` is not `nil`, as if `*print-level*` and `*print-length*` were `nil` and `*print-array*` were not `nil`, regardless of their actual values.

Arrays
  Normally any array other than a vector is printed using `#nA` format. Let n be the rank of the array. Then `#` is printed, then n as a decimal integer, then `A`, then n open parentheses. Next the elements are scanned in row-major order. Imagine the array indices being enumerated in odometer fashion, recalling that the dimensions are numbered from 0 to n-1. Every time the index for dimension j is incremented, the following actions are taken:

  1. If j<n-1, then print a close parenthesis.

  2. If incrementing the index for dimension j caused it to equal dimension j, reset that index to zero and increment dimension j-1 (thereby performing these three steps recursively), unless j=0, in which case simply terminate the entire algorithm. If incrementing the index for dimension j did not cause it to equal dimension j, then print a space.

  3. If j<n-1, then print an open parenthesis.

  This causes the contents to be printed in a format suitable for use as the `:initial-contents` argument to `make-array`.

  The lists effectively printed by this procedure are subject to truncation by `*print-level*` and `*print-length*`.

  If the array is of a specialized type, containing bits or string-characters, then the innermost lists generated by the algorithm given above may instead be printed using bit-vector or string syntax, provided that these innermost lists would not be subject to truncation by `*print-length*`. For example, a 3-by-2-by-4 array of string-characters that would ordinarily be printed as

      #3A(((#\s #\t #\o #\p) (#\s #\p #\o #\t))
          ((#\p #\o #\s #\t) (#\p #\o #\t #\s))
          ((#\t #\o #\p #\s) (#\o #\p #\t #\s)))

  may instead be printed more concisely as

      #3A(("stop" "spot") ("post" "pots") ("tops" "opts"))

  If `*print-array*` is `nil`, then the array is printed in a format (using `#<`) that is concise but not readable.

  X3J13 voted in June 1989 (DATA-IO) to specify that if `*print-readably*` is not `nil` then every object must be printed in a readable form, regardless of other printer control variables. For arrays, the simplest approach is to print them, when `*print-readably*` is not `nil`, as if `*print-level*` and `*print-length*` were `nil` and `*print-array*` were not `nil`, regardless of their actual values.

Random-states
  Common Lisp does not specify a specific syntax for printing objects of type `random-state`. However, every implementation must arrange to print a random-state object in such a way that, within the same implementation of Common Lisp, the function `read` can construct from the printed representation a copy of the random-state object as if the copy had been made by `make-random-state`.

Pathnames
  Common Lisp does not specify a specific syntax for printing objects of type `pathname`. However, every implementation must arrange to print a pathname in such a way that, within the same implementation of Common Lisp, the function `read` can construct from the printed representation an equivalent instance of the pathname object.

  X3J13 voted in June 1989 (PATHNAME-PRINT-READ) to specify that if `*print-escape*` is true, a pathname should be printed by `write` as `#P"..."` where `"..."` is the namestring representation of the pathname. If `*print-escape*` is false, `write` prints a pathname by printing its namestring (presumably without escape characters or surrounding double quotes).

  X3J13 voted in June 1989 (DATA-IO) to specify that if `*print-readably*` is not `nil` then every object must be printed in a readable form, regardless of other printer control variables. For pathnames, the simplest approach is to print them, when `*print-readably*` is not `nil`, as if `*print-escape*` were `nil`, regardless of its actual value.

Structures defined by `defstruct` are printed under the control of the user-specified `:print-function` option to `defstruct`. If the user does not provide a printing function explicitly, then a default printing function is supplied that prints the structure using `#S` syntax (see section 22.1.4).

Any other types are printed in an implementation-dependent manner. It is recommended that printed representations of all such objects begin with the characters `#<` and end with `>` so that the reader will catch such objects and not permit them to be read under normal circumstances. It is specifically and purposely not required that a Common Lisp implementation be able to print an object of type `hash-table`, `readtable`, `package`, `stream`, or `function` in a way that can be read back in successfully by `read`; the use of `#<` syntax is especially recommended for the printing of such objects.

X3J13 voted in June 1989 (DATA-IO) to specify that if `*print-readably*` is not `nil` then every object must be printed in a readable form, regardless of the values of other printer control variables; if this is not possible, then an error of type `print-not-readable` must be signaled to avoid printing an unreadable syntax such as `#<...>`.

X3J13 voted in June 1989 (DATA-IO) to add `print-unreadable-object`, a macro that prints an object using `#<...>` syntax and also takes care of checking the variable `*print-readably*`.

When debugging or when frequently dealing with large or deep objects at top level, the user may wish to restrict the printer from printing large amounts of information. The variables `*print-level*` and `*print-length*` allow the user to control how deep the printer will print and how many elements at a given level the printer will print. Thus the user can see enough of the object to identify it without having to wade through the entire expression.

[Variable]
`*print-readably*`

The default value of `*print-readably*` is `nil`. If `*print-readably*` is true, then printing any object must either produce a printed representation that the reader will accept or signal an error. If printing is successful, the reader will, on reading the printed representation, produce an object that is ``similar as a constant'' (see section 25.1.4) to the object that was printed.

If `*print-readably*` is true and printing a readable printed representation is not possible, the printer signals an error of type `print-not-readable` rather than using an unreadable syntax such as `#<`. The printed representation produced when `*print-readably*` is true might or might not be the same as the printed representation produced when `*print-readably*` is false.

If `*print-readably*` is true and another printer control variable (such as `*print-length*`, `*print-level*`, `*print-escape*`, `*print-gensym*`, `*print-array*`, or an implementation-defined printer control variable) would cause the preceding requirements to be violated, that other printer control variable is ignored.

The printing of interned symbols is not affected by `*print-readably*`.

Note that the ``similar as a constant'' rule for readable printing implies that `#A` or `#(` syntax cannot be used for arrays of element-type other than `t`. An implementation will have to use another syntax or signal a `print-not-readable` error. A `print-not-readable` error will not be signaled for strings or bit-vectors.

All methods for `print-object` must obey `*print-readably*`. This rule applies to both user-defined methods and implementation-defined methods.

The reader control variable `*read-eval*` also affects printing. If `*read-eval*` is false and `*print-readably*` is true, any `print-object` method that would otherwise output a `#.` reader macro must either output something different or signal an error of type `print-not-readable`.

Readable printing of structures and objects of type `standard-object` is controlled by their `print-object` methods, not by their `make-load-form` methods. ``Similarity as a constant'' for these objects is application-dependent and hence is defined to be whatever these methods do.

`*print-readably*` allows errors involving data with no readable printed representation to be detected when writing the file rather than later on when the file is read.

`*print-readably*` is more rigorous than `*print-escape*`; output printed with escapes must be merely generally recognizable by humans, with a good chance of being recognizable by computers, whereas output printed readably must be reliably recognizable by computers.

[Variable]
`*print-escape*`

When this flag is `nil`, then escape characters are not output when an expression is printed. In particular, a symbol is printed by simply printing the characters of its print name. The function `princ` effectively binds `*print-escape*` to `nil`.

When this flag is not `nil`, then an attempt is made to print an expression in such a way that it can be read again to produce an `equal` structure. The function `prin1` effectively binds `*print-escape*` to `t`. The initial value of this variable is `t`.

Compatibility note: `*print-escape*` controls what was called slashification in MacLisp.

[Variable]
`*print-pretty*`

When this flag is `nil`, then only a small amount of whitespace is output when printing an expression.

When this flag is not `nil`, then the printer will endeavor to insert extra whitespace where appropriate to make the expression more readable. A few other simple changes may be made, such as printing `'foo` instead of `(quote foo)`.

The initial value of `*print-pretty*` is implementation-dependent.

X3J13 voted in January 1989 (PRETTY-PRINT-INTERFACE) to adopt a facility for user-controlled pretty printing in Common Lisp (see chapter 27).

[Variable]
`*print-circle*`

When this flag is `nil` (the default), then the printing process proceeds by recursive descent; an attempt to print a circular structure may lead to looping behavior and failure to terminate.

When this flag is not `nil`, then the printer will endeavor to detect cycles in the structure to be printed, and to use `#n=` and `#n#` syntax to indicate the circularities.

X3J13 voted in June 1989 (PRINT-CIRCLE-SHARED) to specify that if `*print-circle*` is true, the printer is required to detect not only cycles but shared substructure, indicating both through the use of `#n=` and `#n#` syntax. As an example, under the specification of the first edition

    (print '(#1=(a #1#) #1#))

might legitimately print `(#1=(A #1#) #1#)` or `(#1=(A #1#) #2=(A #2#))`; the vote specifies that the first form is required.

X3J13 voted in January 1989 (PRINT-CIRCLE-STRUCTURE) to specify that user-defined printing functions for the `defstruct` `:print-function` option, as well as user-defined methods for the CLOS generic function `print-object`, may print objects to the supplied stream using `write`, `print1`, `princ`, `format`, or `print-object` and expect circularities to be detected and printed using `#n#` syntax (when `*print-circle*` is non-`nil`, of course).

It seems to me that the same ought to apply to abbreviation as controlled by `*print-level*` and `*print-length*`, but that was not addressed by this vote.

[Variable]
`*print-base*`

The value of `*print-base*` determines in what radix the printer will print rationals. This may be any integer from `2` to `36`, inclusive; the default value is `10` (decimal radix). For radices above `10`, letters of the alphabet are used to represent digits above `9`.

Compatibility note:MacLisp calls this variable `base`, and its default value is `8`, not `10`.

In both MacLisp and Common Lisp, floating-point numbers are always printed in decimal, no matter what the value of `*print-base*`.

[Variable]
`*print-radix*`

If the variable `*print-radix*` is non-`nil`, the printer will print a radix specifier to indicate the radix in which it is printing a rational number. To prevent confusion of the letter `O` with the digit `0`, and of the letter `B` with the digit `8`, the radix specifier is always printed using lowercase letters. For example, if the current base is twenty-four (decimal), the decimal integer twenty-three would print as `#24rN`. If `*print-base*` is `2`, `8`, or `16`, then the radix specifier used is `#b`, `#o`, or `#x`. For integers, base ten is indicated by a trailing decimal point instead of a leading radix specifier; for ratios, however, `#10r` is used. The default value of `*print-radix*` is `nil`.

[Variable]
`*print-case*`

The `read` function normally converts lowercase characters appearing in symbols to corresponding uppercase characters, so that internally print names normally contain only uppercase characters. However, users may prefer to see output using lowercase letters or letters of mixed case. This variable controls the case (upper, lower, or mixed) in which to print any uppercase characters in the names of symbols when vertical-bar syntax is not used. The value of `*print-case*` should be one of the keywords `:upcase`, `:downcase`, or `:capitalize`; the initial value is `:upcase`.

Lowercase characters in the internal print name are always printed in lowercase, and are preceded by a single escape character or enclosed by multiple escape characters. Uppercase characters in the internal print name are printed in uppercase, in lowercase, or in mixed case so as to capitalize words, according to the value of `*print-case*`. The convention for what constitutes a ``word'' is the same as for the function `string-capitalize`.

X3J13 voted in June 1989 (PRINT-CASE-PRINT-ESCAPE-INTERACTION) to clarify the interaction of `*print-case*` with `*print-escape*`. When `*print-escape*` is `nil`, `*print-case*` determines the case in which to print all uppercase characters in the print name of the symbol. When `*print-escape*` is not `nil`, the implementation has some freedom as to which characters will be printed so as to appear in an ``escape context'' (after an escape character, typically `` , or between multiple escape characters, typically `|`); `*print-case*` determines the case in which to print all uppercase characters that will not appear in an escape context. For example, when the value of `*print-case*` is `:upcase`, an implementation might choose to print the symbol whose print name is `"(S)HE"` as `(S )HE` or as `|(S)HE|`, among other possibilities. When the value of `*print-case*` is `:downcase`, the corresponding output should be `(s )he` or `|(S)HE|`, respectively.

Consider the following test code. (For the sake of this example assume that `readtable-case` is `:upcase` in the current readtable; this is discussed further below.)

    (let ((tabwidth 11))
      (dolist (sym '(|x| |FoObAr| |fOo|))
        (let ((tabstop -1))
          (format t "~&")
          (dolist (escape '(t nil))
            (dolist (case '(:upcase :downcase :capitalize))
              (format t "~VT" (* (incf tabstop) tabwidth))
              (write sym :escape escape :case case)))))
      (format t "~%"))

An implementation that leans heavily on multiple-escape characters (vertical bars) might produce the following output:

    |x|        |x|        |x|        x          x          x
    |FoObAr|   |FoObAr|   |FoObAr|   FoObAr     foobar     Foobar
    |fOo|      |fOo|      |fOo|      fOo        foo        foo

An implementation that leans heavily on single-escape characters (backslashes) might produce the following output:

    \x         \x         \x         x          x          x
    F\oO\bA\r  f\oo\ba\r  F\oo\ba\r  FoObAr     foobar     Foobar
    \fO\o      \fo\o      \fo\o      fOo        foo        foo

These examples are not exhaustive; output using both kinds of escape characters (for example, `|FoO|\bA\r`) is permissible (though ugly).

X3J13 voted in June 1989 (READ-CASE-SENSITIVITY) to add a new `readtable-case` slot to readtables to control automatic case conversion during the reading of symbols. The value of `readtable-case` in the current readtable also affects the printing of unescaped letters (letters appearing in an escape context are always printed in their own case).

- If `readtable-case` is `:upcase`, unescaped uppercase letters are printed in the case specified by `*print-case*` and unescaped lowercase letters are printed in their own case. (If `*print-escape*` is non-`nil`, all lowercase letters will necessarily be escaped.)

- If `readtable-case` is `:downcase`, unescaped lowercase letters are printed in the case specified by `*print-case*` and unescaped uppercase letters are printed in their own case. (If `*print-escape*` is non-`nil`, all uppercase letters will necessarily be escaped.)

- If `readtable-case` is `:preserve`, all unescaped letters are printed in their own case, regardless of the value of `*print-case*`. There is no need to escape any letters, even if `*print-escape*` is non-`nil`, though the X3J13 vote did not prohibit escaping letters in this situation.

- If `readtable-case` is `:invert`, and if all unescaped letters are of the same case, then the case of all the unescaped letters is inverted; but if the unescaped letters are not all of the same case then each is printed in its own case. (Thus `:invert` does not always invert the case; the inversion is conditional.) There is no need to escape any letters, even if `*print-escape*` is non-`nil`, though the X3J13 vote did not prohibit escaping letters in this situation.

Consider the following code.

    ;;; Generate a table illustrating READTABLE-CASE and *PRINT-CASE*.

    (let ((*readtable* (copy-readtable nil))
          (*print-case* *print-case*))
      (format t "READTABLE-CASE *PRINT-CASE*  Symbol-name  Output~
               ~%------------------------------------------------~
               ~%")
      (dolist (readtable-case '(:upcase :downcase :preserve :invert))
        (setf (readtable-case *readtable*) readtable-case)
        (dolist (print-case '(:upcase :downcase :capitalize))
          (dolist (sym '(|ZEBRA| |Zebra| |zebra|))
            (setq *print-case* print-case)
            (format t ":~A~15T:~A~29T~A~42T~A~%"
                      (string-upcase readtable-case)
                      (string-upcase print-case)
                      (symbol-name sym)
                      (prin1-to-string sym)))))))

Note that the call to `prin1-to-string` (the last argument in the call to `format` that is within the nested loops) effectively uses a non-`nil` value for `*print-escape*`.

Assuming an implementation that uses vertical bars around a symbol name if any characters need escaping, the output from this test code should be

    READTABLE-CASE *PRINT-CASE*  Symbol-name  Output
    ------------------------------------------------
    :UPCASE        :UPCASE       ZEBRA        ZEBRA
    :UPCASE        :UPCASE       Zebra        |Zebra|
    :UPCASE        :UPCASE       zebra        |zebra|
    :UPCASE        :DOWNCASE     ZEBRA        zebra
    :UPCASE        :DOWNCASE     Zebra        |Zebra|
    :UPCASE        :DOWNCASE     zebra        |zebra|
    :UPCASE        :CAPITALIZE   ZEBRA        Zebra
    :UPCASE        :CAPITALIZE   Zebra        |Zebra|
    :UPCASE        :CAPITALIZE   zebra        |zebra|
    :DOWNCASE      :UPCASE       ZEBRA        |ZEBRA|
    :DOWNCASE      :UPCASE       Zebra        |Zebra|
    :DOWNCASE      :UPCASE       zebra        ZEBRA
    :DOWNCASE      :DOWNCASE     ZEBRA        |ZEBRA|
    :DOWNCASE      :DOWNCASE     Zebra        |Zebra|
    :DOWNCASE      :DOWNCASE     zebra        zebra
    :DOWNCASE      :CAPITALIZE   ZEBRA        |ZEBRA|
    :DOWNCASE      :CAPITALIZE   Zebra        |Zebra|
    :DOWNCASE      :CAPITALIZE   zebra        Zebra
    :PRESERVE      :UPCASE       ZEBRA        ZEBRA
    :PRESERVE      :UPCASE       Zebra        Zebra
    :PRESERVE      :UPCASE       zebra        zebra
    :PRESERVE      :DOWNCASE     ZEBRA        ZEBRA
    :PRESERVE      :DOWNCASE     Zebra        Zebra
    :PRESERVE      :DOWNCASE     zebra        zebra
    :PRESERVE      :CAPITALIZE   ZEBRA        ZEBRA
    :PRESERVE      :CAPITALIZE   Zebra        Zebra
    :PRESERVE      :CAPITALIZE   zebra        zebra
    :INVERT        :UPCASE       ZEBRA        zebra
    :INVERT        :UPCASE       Zebra        Zebra
    :INVERT        :UPCASE       zebra        ZEBRA
    :INVERT        :DOWNCASE     ZEBRA        zebra
    :INVERT        :DOWNCASE     Zebra        Zebra
    :INVERT        :DOWNCASE     zebra        ZEBRA
    :INVERT        :CAPITALIZE   ZEBRA        zebra
    :INVERT        :CAPITALIZE   Zebra        Zebra
    :INVERT        :CAPITALIZE   zebra        ZEBRA

This illustrates all combinations for `readtable-case` and `*print-case*`.

[Variable]
`*print-gensym*`

The `*print-gensym*` variable controls whether the prefix `#:` is printed before symbols that have no home package. The prefix is printed if the variable is not `nil`. The initial value of `*print-gensym*` is `t`.

[Variable]
`*print-level*` `
``*print-length*`

The `*print-level*` variable controls how many levels deep a nested data object will print. If `*print-level*` is `nil` (the initial value), then no control is exercised. Otherwise, the value should be an integer, indicating the maximum level to be printed. An object to be printed is at level `0`; its components (as of a list or vector) are at level `1`; and so on. If an object to be recursively printed has components and is at a level equal to or greater than the value of `*print-level*`, then the object is printed as simply `#`.

The `*print-length*` variable controls how many elements at a given level are printed. A value of `nil` (the initial value) indicates that there be no limit to the number of components printed. Otherwise, the value of `*print-length*` should be an integer. Should the number of elements of a data object exceed the value `*print-length*`, the printer will print three dots, `...`, in place of those elements beyond the number specified by `*print-length*`. (In the case of a dotted list, if the list contains exactly as many elements as the value of `*print-length*`, and in addition has the non-null atom terminating it, that terminating atom is printed rather than the three dots.)

`*print-level*` and `*print-length*` affect the printing not only of lists but also of vectors, arrays, and any other object printed with a list-like syntax. They do not affect the printing of symbols, strings, and bit-vectors.

The Lisp reader will normally signal an error when reading an expression that has been abbreviated because of level or length limits. This signal is given because the `#` dispatch character normally signals an error when followed by whitespace or `)`, and because `...` is defined to be an illegal token, as are all tokens consisting entirely of periods (other than the single dot used in dot notation).

As an example, table 22-6 shows the ways the object

    (if (member x y) (+ (car x) 3) '(foo . #(a b c d "Baz")))

would be printed for various values of `*print-level*` (in the column labeled v) and `*print-length*` (in the column labeled n).

    ----------------------------------------------------------------
    Table 22-6: Examples of Print Level and Print Length Abbreviation

    v  n  Output
    ======================================================
    0  1  #
    1  1  (if ...)
    1  2  (if # ...)
    1  3  (if # # ...)
    1  4  (if # # #)
    2  1  (if ...)
    2  2  (if (member x ...) ...)
    2  3  (if (member x y) (+ # 3) ...)
    3  2  (if (member x ...) ...)
    3  3  (if (member x y) (+ (car x) 3) ...)
    3  4  (if (member x y) (+ (car x) 3) '(foo . #(a b c d ...)))
    3  5  (if (member x y) (+ (car x) 3) '(foo . #(a b c d "Baz")))
    ======================================================
    ----------------------------------------------------------------

[Variable]
`*print-array*`

If `*print-array*` is `nil`, then the contents of arrays other than strings are never printed. Instead, arrays are printed in a concise form (using `#<`) that gives enough information for the user to be able to identify the array but does not include the entire array contents. If `*print-array*` is not `nil`, non-string arrays are printed using `#(`, `#*`, or `#nA` syntax.

Notice of correction. In the first edition, the preceding paragraph mentioned the nonexistent variable `print-array` instead of `*print-array*`.

The initial value of `*print-array*` is implementation-dependent.

[Macro]
`with-standard-io-syntax` `{declaration}*` `{form}*`

X3J13 voted in June 1989 (DATA-IO) to add the macro `with-standard-io-syntax`. Within the dynamic extent of the body, all reader/printer controlvariables, including any implementation-defined ones not specified byCommon Lisp, are bound to values that produce standard read/printbehavior. Table 22-7 shows the values to which standard Common Lisp variables are bound.

The values returned by `with-standard-io-syntax` are the values of the last body form, or `nil` if there are no body forms.

The intent is that a pair of executions, as shown in the following example, should provide reasonable reliable communication of data from one Lisp process to another:

    ;;; Write DATA to a file.
    (with-open-file (file pathname :direction :output)
      (with-standard-io-syntax
        (print data file)))

    ;;; ...  Later, in another Lisp:
    (with-open-file (file pathname :direction :input)
      (with-standard-io-syntax
        (setq data (read file))))

Using `with-standard-io-syntax` to bind all the variables, instead of using `let` and explicit bindings, ensures that nothing is overlooked and avoids problems with implementation-defined reader/printer control variables. If the user wishes to use a non-standard value for some variable, such as `*package*` or `*read-eval*`, it can be bound by `let` inside the body of `with-standard-io-syntax`. For example:

    ;;; Write DATA to a file.  Forbid use of #. syntax.
    (with-open-file (file pathname :direction :output)
      (let ((*read-eval* nil))
        (with-standard-io-syntax
          (print data file))))

    ;;; Read DATA from a file.  Forbid use of #. syntax.
    (with-open-file (file pathname :direction :input)
      (let ((*read-eval* nil))
        (with-standard-io-syntax
          (setq data (read file)))))

Similarly, a user who dislikes the arbitrary choice of values for `*print-circle*` and `*print-pretty*` can bind these variables to other values inside the body.

The X3J13 vote left it unclear whether `with-standard-io-syntax` permits declarations to appear before the body of the macro call. I believe that was the intent, and this is reflected in the syntax shown above; but this is only my interpretation.

    ----------------------------------------------------------------
    Table 22-7: Standard Bindings for I/O Control Variables

    Variable                     Value
    ===========================================================
    *package*                    the common-lisp-user package
    *print-array*                t
    *print-base*                 10
    *print-case*                 :upcase
    *print-circle*               nil
    *print-escape*               t
    *print-gensym*               t
    *print-length*               nil
    *print-level*                nil
    *print-lines*                nil *
    *print-miser-width*          nil *
    *print-pprint-dispatch*      nil *
    *print-pretty*               nil
    *print-radix*                nil
    *print-readably*             t
    *print-right-margin*         nil *
    *read-base*                  10
    *read-default-float-format*  single-float
    *read-eval*                  t
    *read-suppress*              nil
    *readtable*                  the standard readtable

    * X3J13 voted in June 1989 (PRETTY-PRINT-INTERFACE)
    to introduce the printer control variables *print-right-margin*,
    *print-miser-width*, *print-lines*, and
    *print-pprint-dispatch* (see section 27.2) but did not
    specify the values to which with-standard-io-syntax should
    bind them.  I recommend that all four should be bound to nil.
    ----------------------------------------------------------------

Next: Input Functions Up: Printed Representation of Previous: The Readtable