This section describes the default behavior of
print-object
methods for the standardized types.
Integers are printed in the radix specified by the current output base
in positional notation, most significant digit first.
If appropriate, a radix specifier can be printed; see *print-radix*
.
If an integer is negative, a minus sign is printed and then the
absolute value of the integer is printed.
The integer zero is represented
by the single digit 0
and never has a sign.
A decimal point might be printed,
depending on the value of *print-radix*
.
For related information about the syntax of an integer, see Section 2.3.2.1.1 (Syntax of an Integer).
Ratios are printed as follows:
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 current output base;
they are obtained as if by
numerator
and denominator
, and so ratios
are printed in reduced form (lowest terms).
If appropriate, a radix specifier can be printed; see
*print-radix*
.
If the ratio is negative, a minus sign is printed before the numerator.
For related information about the syntax of a ratio, see Section 2.3.2.1.2 (Syntax of a Ratio).
If the magnitude of the float is either zero or between 10^-3 (inclusive)
and 10^7 (exclusive), it is 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 sign of the number
(as determined by float-sign
)
is negative, then a minus sign is printed before the number.
If the format of the number
does not match that specified by
*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 float
might be printed as 2.71828S0
.
For non-zero magnitudes outside of the range 10^-3 to 10^7,
a float is 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
*read-default-float-format*
, then the exponent marker E
is used.
Finally, the power of ten 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 float
is printed as 6.02S23
.
For related information about the syntax of a float, see Section 2.3.2.2 (Syntax of a Float).
A complex 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.
For related information about the syntax of a complex, see Section 2.3.2.3 (Syntax of a Complex) and Section 2.4.8.11 (Sharpsign C).
The printed representation of a number must not contain escape characters; see Section 2.3.1.1.1 (Escape Characters and Potential Numbers).
When printer escaping is disabled,
a character prints as itself;
it is sent directly to the output stream.
When printer escaping is enabled,
then #\
syntax is used.
When the printer types out the name of a character,
it uses the same table as the #\
reader macro would use;
therefore any character name that is typed out
is acceptable as input (in that implementation).
If a non-graphic character has a standardized name5,
that name is preferred over non-standard names
for printing in #\
notation.
For the graphic standard characters,
the character itself is always used
for printing in #\
notation—even if
the character also has a name5.
For details about the #\
reader macro, see Section 2.4.8.1 (Sharpsign Backslash).
When printer escaping is disabled,
only the characters of the symbol's name are output
(but the case in which to print characters in the name is
controlled by *print-case*
;
see Section 22.1.3.3.2 (Effect of Readtable Case on the Lisp Printer)).
The remainder of this section applies only when printer escaping is enabled.
When printing a symbol, the printer inserts enough
single escape and/or multiple escape
characters (backslashes and/or vertical-bars) so that if
read
were called with the same *readtable*
and
with *read-base*
bound to the current output base, it
would return the same symbol (if it is not
apparently uninterned) or an uninterned symbol
with the same print name (otherwise).
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 the value of *read-base*
were 16
.
For additional restrictions concerning characters with nonstandard syntax types in the current readtable, see the variable *print-readably*
For information about how the Lisp reader parses symbols, see Section 2.3.4 (Symbols as Tokens) and Section 2.4.8.5 (Sharpsign Colon).
nil
might be printed as ()
when *print-pretty*
is true
and printer escaping is enabled.
Package prefixes are printed if necessary.
The rules for package prefixes 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
package prefix; otherwise, it is printed with a package prefix.
A symbol that is apparently uninterned is printed
preceded by “#:
”
if *print-gensym*
is true and printer escaping is enabled;
if *print-gensym*
is false or printer escaping is disabled,
then the symbol is printed without a prefix,
as if it were in the current package.
Because the #:
syntax does not intern the
following symbol, it is necessary to use circular-list syntax
if *print-circle*
is true 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 false, but as (#1=#:foo #1#)
if *print-circle*
were true.
A summary of the preceding package prefix rules follows:
foo:bar
foo:bar
is printed when symbol bar
is external in its home package foo
and is not accessible in the current package.
foo::bar
foo::bar
is printed when bar
is internal in its home package
foo
and is not accessible in the current package.
:bar
:bar
is printed when the home package of bar
is the KEYWORD
package.
#:bar
#:bar
is printed when bar
is apparently uninterned,
even in the pathological case that bar
has no home package but is nevertheless somehow accessible
in the current package.
When printer escaping is disabled, or the characters under consideration are not already quoted specifically by single escape or multiple escape syntax, the readtable case of the current readtable affects the way the Lisp printer writes symbols in the following ways:
When the readtable case is :upcase,
uppercase characters
are printed in the case specified by *print-case*
, and
lowercase characters are printed in their own case.
When the readtable case is :downcase,
uppercase characters are printed in their own case, and
lowercase characters
are printed in the case specified by *print-case*
.
When the readtable case is :preserve,
all alphabetic characters are printed in their own case.
When the readtable case is :invert, the case of all alphabetic characters in single case symbol names is inverted. Mixed-case symbol names are printed as is.
The rules for escaping alphabetic characters in symbol names are affected by
the readtable-case
if printer escaping is enabled.
Alphabetic characters are escaped as follows:
When the readtable case is :upcase,
all lowercase characters must be escaped.
When the readtable case is :downcase,
all uppercase characters must be escaped.
When the readtable case is :preserve,
no alphabetic characters need be escaped.
When the readtable case is :invert, no alphabetic characters need be escaped.
(defun test-readtable-case-printing () (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 (symbol '(|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 symbol) (prin1-to-string symbol)))))))
The output from (test-readtable-case-printing)
should be as follows:
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
The characters of the string are output in order.
If printer escaping is enabled,
a double-quote is output before and after, and all
double-quotes and single escapes are preceded by backslash.
The printing of strings is not affected by *print-array*
.
Only the active elements of the string are printed.
For information on how the Lisp reader parses strings, see Section 2.4.5 (Double-Quote).
Wherever possible, list notation is preferred over dot notation. Therefore the following algorithm is used to print a cons x:
Actually, the above algorithm is only used when *print-pretty*
is false. When *print-pretty*
is true (or
when pprint
is used),
additional whitespace1
may replace the use of a single space, and a more elaborate algorithm with similar goals but more presentational flexibility is used; see Section 22.1.2 (Printer Dispatching).
Although the two expressions below are equivalent, and the reader accepts either one and produces the same cons, the printer always prints such a cons in the second form.
(a . (b . ((c . (d . nil)) . (e . nil)))) (a b (c d) e)
The printing of conses is affected by *print-level*
,
*print-length*
, and *print-circle*
.
Following are examples of printed representations of lists:
(a . b) ;A dotted pair of a and b (a.b) ;A list of one element, the symbol named a.b (a. b) ;A list of two elements a. and b (a .b) ;A list of two elements a and .b (a b . c) ;A dotted list of a and b with c at the end; two conses .iot ;The symbol whose name is .iot (. b) ;Invalid -- an error is signaled if an attempt is made to read ;this syntax. (a .) ;Invalid -- an error is signaled. (a .. b) ;Invalid -- an error is signaled. (a . . b) ;Invalid -- an error is signaled. (a b c ...) ;Invalid -- an error is signaled. (a \. b) ;A list of three elements a, ., and b (a |.| b) ;A list of three elements a, ., and b (a \... b) ;A list of three elements a, ..., and b (a |...| b) ;A list of three elements a, ..., and b
For information on how the Lisp reader parses lists and conses, see Section 2.4.1 (Left-Parenthesis).
A bit vector is printed as #*
followed by the bits of the bit vector
in order. If *print-array*
is false, then the bit vector is
printed in a format (using #<
) that is concise but not readable.
Only the active elements of the bit vector are printed.
For information on Lisp reader parsing of bit vectors, see Section 2.4.8.4 (Sharpsign Asterisk).
If *print-array*
is true
and *print-readably*
is false,
any
vector
other than a string or bit vector is printed using
general-vector syntax; this means that information
about specialized vector representations does not appear.
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
each such additional element preceded by
a space if *print-pretty*
is false,
or whitespace1 if *print-pretty*
is true.
A right-parenthesis after the last element
terminates the printed representation of the vector.
The printing of vectors
is affected by *print-level*
and *print-length*
.
If the vector has a fill pointer,
then only those elements below
the fill pointer are printed.
If both *print-array*
and *print-readably*
are false,
the vector is not printed as described above,
but in a format (using #<
) that is concise but not readable.
If *print-readably*
is true,
the vector prints in an implementation-defined manner;
see the variable *print-readably*.
For information on how the Lisp reader parses these “other vectors,” see Section 2.4.8.3 (Sharpsign Left-Parenthesis).
If *print-array*
is true
and *print-readably*
is false,
any
array other than a vector is printed
using #
n
A
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,
using write
on each element,
and separating elements from each other with whitespace1.
The array's dimensions are numbered 0 to n
-1 from left to right,
and are enumerated with the rightmost index changing fastest.
Every time the index for dimension j
is incremented,
the following actions are taken:
j
< n
-1, then a close parenthesis is printed.
j
caused it to equal
dimension j
, that index is reset to zero and the
index for dimension j
-1 is incremented (thereby performing these three steps recursively),
unless j
=0, in which case the entire algorithm is terminated.
If incrementing the index for dimension j
did not cause it to
equal dimension j
, then a space is printed.
j
< n
-1, then an open parenthesis is printed.
This causes the contents to be printed in a format suitable for
:initial-contents 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 characters,
then the innermost lists generated by the algorithm given above can instead
be printed using bit-vector or string syntax, provided that these innermost
lists would not be subject to truncation by *print-length*
.
If both *print-array*
and *print-readably*
are false,
then the array is printed
in a format (using #<
) that is concise but not readable.
If *print-readably*
is true,
the array prints in an implementation-defined manner;
see the variable *print-readably*.
In particular,
this may be important for arrays having some dimension 0
.
For information on how the Lisp reader parses these “other arrays,” see Section 2.4.8.12 (Sharpsign A).
(let ((a (make-array '(3 3)))
(*print-pretty* t)
(*print-array* t))
(dotimes (i 3) (dotimes (j 3) (setf (aref a i j) (format nil "<~D,~D>" i j))))
(print a)
(print (make-array 9 :displaced-to a)))
▷ #2A(("<0,0>" "<0,1>" "<0,2>")
▷ ("<1,0>" "<1,1>" "<1,2>")
▷ ("<2,0>" "<2,1>" "<2,2>"))
▷ #("<0,0>" "<0,1>" "<0,2>" "<1,0>" "<1,1>" "<1,2>" "<2,0>" "<2,1>" "<2,2>")
→ #<ARRAY 9 indirect 36363476>
A specific syntax for printing objects of type random-state
is
not specified. However, every implementation
must arrange to print a random state object in such a way that,
within the same implementation, 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
.
If the type random state is effectively implemented
by using the machinery for defstruct
,
the usual structure syntax can then be used for printing
random state
objects; one might look something like
#S(RANDOM-STATE :DATA #(14 49 98436589 786345 8734658324 ... ))
where the components are implementation-dependent.
When printer escaping is enabled,
the syntax #P"..."
is how a
pathname is printed by write
and the other functions herein described.
The "..."
is the namestring representation of the pathname.
When printer escaping is disabled,
write
writes a pathname P
by writing (namestring
P)
instead.
For information on how the Lisp reader parses pathnames, see Section 2.4.8.14 (Sharpsign P).
By default, a structure of type S is printed using #S
syntax.
This behavior can be customized by specifying a :print-function
or :print-object option to the defstruct
form that defines S,
or by writing a print-object
method
that is specialized for objects of type S.
Different structures might print out in different ways; the default notation for structures is:
#S(structure-name {slot-key slot-value}*)
where #S
indicates structure syntax,
structure-name is a structure name,
each slot-key is an initialization argument name
for a slot in the structure,
and each corresponding slot-value is a representation
of the object in that slot.
For information on how the Lisp reader parses structures, see Section 2.4.8.13 (Sharpsign S).
Other objects are printed in an implementation-dependent manner. It is not required that an implementation print those objects readably.
For example, hash tables, readtables, packages, streams, and functions might not print readably.
A common notation to use in this circumstance is #<...>
.
Since #<
is not readable by the Lisp reader,
the precise format of the text which follows is not important,
but a common format to use is that provided by the print-unreadable-object
macro.
For information on how the Lisp reader treats this notation, see Section 2.4.8.20 (Sharpsign Less-Than-Sign). For information on how to notate objects that cannot be printed readably, see Section 2.4.8.6 (Sharpsign Dot).