Common Lisp the Language, 2nd Edition


next up previous contents index
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.
old_change_begin
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.
old_change_end

change_begin

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*.
change_end

old_change_begin

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*).
old_change_end

change_begin

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*.
change_end

old_change_begin

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

change_begin

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*.
change_end

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.

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

change_begin

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

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.

old_change_begin
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.
old_change_end

change_begin

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.
change_end


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.


old_change_begin

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

change_begin

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

old_change_begin

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.
old_change_end

change_begin

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*.
change_end
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)

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

change_begin

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.
change_end

old_change_begin

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.
old_change_end

change_begin

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*.
change_end
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.
old_change_begin
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.

old_change_end

change_begin

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.
change_end
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.
old_change_begin
The lists effectively printed by this procedure are subject to truncation by *print-level* and *print-length*.
old_change_end
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"))

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

change_begin

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.
change_end
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.
old_change_begin
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.
old_change_end

change_begin

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.

change_end

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).

old_change_begin
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.
old_change_end

change_begin
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*.
change_end

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.

change_begin

[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.
change_end


[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.

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


[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.

old_change_begin
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.
old_change_end

change_begin
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.
change_end


[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.

change_begin
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).

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*.


change_end


[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.

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

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

change_begin

[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. 
----------------------------------------------------------------

change_end



next up previous contents index
Next: Input Functions Up: Printed Representation of Previous: The Readtable


AI.Repository@cs.cmu.edu