emacs.d/clones/lisp/www.cs.cmu.edu/Groups/AI/html/cltl/clm/node193.html

1062 lines
51 KiB
HTML
Raw Normal View History

2022-08-26 19:11:35 +02:00
<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
<!Converted with LaTeX2HTML 0.6.5 (Tue Nov 15 1994) by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds >
<HEAD>
<TITLE>22.1.6. What the Print Function Produces</TITLE>
</HEAD>
<BODY>
<meta name="description" value=" What the Print Function Produces">
<meta name="keywords" value="clm">
<meta name="resource-type" value="document">
<meta name="distribution" value="global">
<P>
<b>Common Lisp the Language, 2nd Edition</b>
<BR> <HR><A NAME=tex2html3949 HREF="node194.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html3947 HREF="node187.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html3943 HREF="node192.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html3951 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html3952 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html3950 HREF="node194.html"> Input Functions</A>
<B>Up:</B> <A NAME=tex2html3948 HREF="node187.html"> Printed Representation of </A>
<B> Previous:</B> <A NAME=tex2html3944 HREF="node192.html"> The Readtable</A>
<HR> <P>
<H2><A NAME=SECTION002616000000000000000>22.1.6. What the Print Function Produces</A></H2>
<P>
<A NAME=PRINTER>The</A>
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.
<P>
How an expression is printed depends on its data type, as described
in the following paragraphs.
<P>
<DL COMPACT><DT><i>Integers</i>
<DD>
If appropriate, a radix specifier may be printed; see the
variable <tt>*print-radix*</tt>.
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 <tt>*print-base*</tt>
in the usual positional notation, most significant digit first.
The number zero is represented
by the single digit <tt>0</tt> and never has a sign.
A decimal point may then be printed, depending on the value
of <tt>*print-radix*</tt>.
<P>
<DT><i>Ratios</i>
<DD>
If appropriate, a radix specifier may be printed; see the variable
<tt>*print-radix*</tt>.
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 <tt>/</tt>; then the denominator. The numerator and denominator are
both printed in the radix specified by the variable <tt>*print-base*</tt>; they are obtained as if by
the <tt>numerator</tt> and <tt>denominator</tt> functions, and so ratios
are always printed in reduced form (lowest terms).
<P>
<DT><i>Floating-point numbers</i>
<DD>
If the sign of the number (as determined by the function <tt>float-sign</tt>)
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 <IMG ALIGN=BOTTOM ALT="" SRC="_24769_tex2html_wrap42653.gif"> (inclusive)
and <IMG ALIGN=BOTTOM ALT="" SRC="_24769_tex2html_wrap42697.gif"> (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
<tt>*read-default-float-format*</tt>, then the exponent marker for
that format and the digit <tt>0</tt> are also printed.
For example, the base of the natural logarithms as a short-format
floating-point number might be printed as <tt>2.71828S0</tt>.
<P>
For non-zero magnitudes
outside of the range <IMG ALIGN=BOTTOM ALT="" SRC="_24769_tex2html_wrap42653.gif">
to <IMG ALIGN=BOTTOM ALT="" SRC="_24769_tex2html_wrap42697.gif">, 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
<tt>*read-default-float-format*</tt>, then the exponent marker <tt>E</tt>
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 <tt>6.02S23</tt>.
<P>
<DT><i>Complex numbers</i>
<DD>
A complex number is printed as <tt>#C</tt>,
an open parenthesis,
the printed representation of its real part, a space,
the printed representation of its imaginary part, and finally
a close parenthesis.
</dl>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif">
<dl compact>
<DT><i>Characters</i>
<DD>
When <tt>*print-escape*</tt> is <tt>nil</tt>, a character prints as itself;
it is sent directly to the output stream.
When <tt>*print-escape*</tt> is not <tt>nil</tt>, then <tt>#\</tt> syntax is used.
For example, the
printed representation of the character <tt>#\A</tt> with control and meta
bits on would be <tt>#\CONTROL-META-A</tt>, and that of <tt>#\a</tt> with
control and meta bits on would be <tt>#\CONTROL-META-\a</tt>.
</dl>
<img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
<dl compact><dd>
X3J13 voted in June 1989 (DATA-IO) <A NAME=22097>&#160;</A> to specify that if <tt>*print-readably*</tt>
is not <tt>nil</tt> 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 <tt>#\</tt> syntax when <tt>*print-readably*</tt>
is not <tt>nil</tt>, regardless of the value of <tt>*print-escape*</tt>.
</dl>
<img align=bottom alt="change_end" src="gif/change_end.gif">
<p>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif">
<dl compact>
<DT><i>Symbols</i>
<DD>
When <tt>*print-escape*</tt> is <tt>nil</tt>, 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 <tt>*print-case*</tt>).
</dl>
<img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
<dl compact><dd>
X3J13 voted in June 1989 (READ-CASE-SENSITIVITY) <A NAME=22112>&#160;</A>
to specify that the new <tt>readtable-case</tt> 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 <tt>*print-escape*</tt>.
</dl>
<img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif">
<dl compact>
<dd>
The remaining paragraphs describing the printing of symbols cover
the situation when <tt>*print-escape*</tt> is not <tt>nil</tt>.
</dl>
<img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
<dl compact><dd>
X3J13 voted in June 1989 (DATA-IO) <A NAME=22121>&#160;</A> to specify that if <tt>*print-readably*</tt>
is not <tt>nil</tt> 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 <tt>*print-readably*</tt> is not <tt>nil</tt>, as if <tt>*print-escape*</tt>
were not <tt>nil</tt>, regardless of the actual value of <tt>*print-escape*</tt>.
</dl>
<img align=bottom alt="change_end" src="gif/change_end.gif">
<dl compact><dd>
<P>
Backslashes <tt> </tt> and
vertical bars <tt>|</tt> 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 <A HREF="node189.html#PARSETOKENSSECTION">22.1.2</A>).
In making this decision, it is assumed that the value of <tt>*print-base*</tt>
being used for printing would be used as the value of <tt>*read-base*</tt>
used for reading; the value of <tt>*read-base*</tt> at the time of printing
is irrelevant. For example, if the value of <tt>*print-base*</tt> were <tt>16</tt>
when printing the symbol <tt>face</tt>, it would have to be printed as
<tt> FACE</tt> or <tt> Face</tt> or <tt>|FACE|</tt>, because the token
<tt>face</tt> would be read as a hexadecimal
number (decimal value 64206) if <tt>*read-base*</tt> were <tt>16</tt>.
</dl>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif">
<dl compact><dd>
The case in which to print any
uppercase characters in the print name is controlled by the
variable <tt>*print-case*</tt>.
</dl>
<img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
<dl compact><dd>
X3J13 voted in June 1989 (PRINT-CASE-PRINT-ESCAPE-INTERACTION) <A NAME=22149>&#160;</A>
to clarify the interaction of <tt>*print-case*</tt> with <tt>*print-escape*</tt>;
see <tt>*print-case*</tt>.
</dl>
<img align=bottom alt="change_end" src="gif/change_end.gif">
<dl compact><dd>
<P>
As a special case [no pun intended], <tt>nil</tt> may sometimes be printed as <tt>()</tt> instead,
when <tt>*print-escape*</tt> and <tt>*print-pretty*</tt> are both not <tt>nil</tt>.
<P>
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 <A HREF="node111.html#XPACK">11</A>.
</dl>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif">
<dl compact><dd>
A symbol that is uninterned (has no home package) is printed
preceded by <tt>#:</tt> if the variables <tt>*print-gensym*</tt>
and <tt>*print-escape*</tt> are both non-<tt>nil</tt>;
if either is <tt>nil</tt>, then the symbol is printed without
a prefix, as if it were in the current package.
</dl>
<img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
<dl compact><dd>
X3J13 voted in June 1989 (DATA-IO) <A NAME=22168>&#160;</A> to specify that if <tt>*print-readably*</tt>
is not <tt>nil</tt> 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 <tt>*print-readably*</tt> is not <tt>nil</tt>, as if <tt>*print-escape*</tt>
and <tt>*print-gensym*</tt>
were not <tt>nil</tt>, regardless of their actual values.
</dl>
<img align=bottom alt="change_end" src="gif/change_end.gif">
<p>
<hr>
<b>Implementation note:</b> Because the <tt>#:</tt> syntax does not intern the
following symbol, it is necessary to use circular-list syntax
if <tt>*print-circle*</tt> is not <tt>nil</tt> and
the same uninterned symbol appears several times in an expression
to be printed. For example, the result of
<P><pre>
(let ((x (make-symbol &quot;FOO&quot;))) (list x x))
</pre><P>
would be printed as
<P><pre>
<tt>(#:foo #:foo)</tt>
</pre><P>
if <tt>*print-circle*</tt>
were <tt>nil</tt>, but as
<P><pre>
<tt>(#1=#:foo #1#)</tt>
</pre><P>
if <tt>*print-circle*</tt>
were not <tt>nil</tt>.
<hr>
<P>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif">
<dl compact>
<dd>
The case in which symbols are to be printed is controlled by the variable
<tt>*print-case*</tt>.
</dl>
<img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<p>
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
<dl compact>
<dd>
It is also controlled by <tt>*print-escape*</tt> and the <tt>readtable-case</tt> slot of the current
readtable (the value of <tt>*readtable*</tt>).
</dl>
<img align=bottom alt="change_end" src="gif/change_end.gif">
<p>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif">
<dl compact>
<DT><i>Strings</i>
<DD>
The characters of the string are output in order.
If <tt>*print-escape*</tt> is not <tt>nil</tt>, 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 <tt>*print-array*</tt>.
If the string has a fill pointer, then only those characters below
the fill pointer are printed.
</dl>
<img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
<dl compact><dd>
X3J13 voted in June 1989 (DATA-IO) <A NAME=22209>&#160;</A> to specify that if <tt>*print-readably*</tt>
is not <tt>nil</tt> 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 <tt>*print-readably*</tt> is not <tt>nil</tt>, as if <tt>*print-escape*</tt>
were not <tt>nil</tt>, regardless of the actual value of <tt>*print-escape*</tt>.
</dl>
<img align=bottom alt="change_end" src="gif/change_end.gif">
<dl compact>
<DT><i>Conses</i>
<DD>
Wherever possible, list notation is preferred over dot
notation. Therefore the following algorithm is used:
<OL><LI> Print an open parenthesis, <tt>(</tt>.
<LI> Print the <i>car</i> of the cons.
<LI> If the <i>cdr</i> is a cons, make it the current cons, print a space, and go to step 2.
<LI> If the <i>cdr</i> is not null, print a space, a dot, a space, and the <i>cdr</i>.
<LI> Print a close parenthesis, <tt>)</tt>.
</OL>
<P>
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.
<P><pre>
(a . (b . ((c . (d . <tt>nil</tt>)) . (e . <tt>nil</tt>))))
(a b (c d) e)
</pre><P>
</dl>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif">
<dl compact><dd>
The printing of conses is affected by the variables <tt>*print-level*</tt>
and <tt>*print-length*</tt>.
</dl>
<img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
<dl compact><dd>
X3J13 voted in June 1989 (DATA-IO) <A NAME=22236>&#160;</A> to specify that if <tt>*print-readably*</tt>
is not <tt>nil</tt> 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 <tt>*print-readably*</tt> is not <tt>nil</tt>, as if <tt>*print-level*</tt>
and <tt>*print-length*</tt> were <tt>nil</tt>, regardless of their actual values.
</dl>
<img align=bottom alt="change_end" src="gif/change_end.gif">
<p>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif">
<dl compact>
<DT><i>Bit-vectors</i>
<DD>
A bit-vector is printed as <tt>#*</tt> followed by the bits of the bit-vector
in order. If <tt>*print-array*</tt> is <tt>nil</tt>, however, then the bit-vector is
printed in a format (using <tt>#&lt;</tt>) that is concise but not readable.
If the bit-vector has a fill pointer, then only those bits below
the fill pointer are printed.
</dl>
<img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<p>
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
<dl compact><dd>
X3J13 voted in June 1989 (DATA-IO) <A NAME=22253>&#160;</A> to specify that if <tt>*print-readably*</tt>
is not <tt>nil</tt> 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 <tt>*print-readably*</tt> is not <tt>nil</tt>, as if <tt>*print-array*</tt>
were not <tt>nil</tt>, regardless of the actual value of <tt>*print-array*</tt>.
</dl>
<img align=bottom alt="change_end" src="gif/change_end.gif">
<dl compact>
<DT><i>Vectors</i>
<DD>
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 <tt>#()</tt>. The
printed representation of a non-zero-length vector begins with <tt>#(</tt>.
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.
</dl>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif">
<dl compact><dd>
The
printing of vectors is affected by the variables <tt>*print-level*</tt> and
<tt>*print-length*</tt>.
If the vector has a fill pointer, then only those elements below
the fill pointer are printed.
<P>
If <tt>*print-array*</tt> is <tt>nil</tt>, however, then the vector is not printed
as described above, but
in a format (using <tt>#&lt;</tt>) that is concise but not readable.
</dl>
<img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<p>
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
<dl compact><dd>
X3J13 voted in June 1989 (DATA-IO) <A NAME=22273>&#160;</A> to specify that if <tt>*print-readably*</tt>
is not <tt>nil</tt> 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 <tt>*print-readably*</tt> is not <tt>nil</tt>, as if <tt>*print-level*</tt>
and <tt>*print-length*</tt> were <tt>nil</tt> and <tt>*print-array*</tt> were not <tt>nil</tt>,
regardless of their actual values.
</dl>
<img align=bottom alt="change_end" src="gif/change_end.gif">
<dl compact>
<DT><i>Arrays</i>
<DD>
Normally any array other than a vector is printed
using <tt>#<i>n</i>A</tt> format. Let <i>n</i> be the rank of the array.
Then <tt>#</tt> is printed, then <i>n</i> as a decimal integer,
then <tt>A</tt>, then <i>n</i> 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 <i>n</i>-1. Every time the index for
dimension <i>j</i> is incremented, the following actions are taken:<p>
<OL><LI>
If <i>j</i>&lt;<i>n</i>-1, then print a close parenthesis.
<P>
<LI>
If incrementing the index for dimension <i>j</i> caused it to equal
dimension <i>j</i>, reset that index to zero and increment dimension
<i>j</i>-1 (thereby performing these three steps recursively),
unless <i>j</i>=0, in which case simply terminate the entire algorithm.
If incrementing the index for dimension <i>j</i> did not cause it to
equal dimension <i>j</i>, then print a space.
<P>
<LI>
If <i>j</i>&lt;<i>n</i>-1, then print an open parenthesis.<p>
</OL>
This causes the contents to be printed in a format suitable for
use as the <tt>:initial-contents</tt> argument to <tt>make-array</tt>.
</dl>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif">
<dl compact><dd>
The lists effectively printed by this procedure are subject to
truncation by <tt>*print-level*</tt> and <tt>*print-length*</tt>.
</dl>
<img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<dl compact><dd>
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 <tt>*print-length*</tt>. For example,
a 3-by-2-by-4 array of string-characters that would ordinarily be printed as
<P><pre>
#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)))
</pre><P>
may instead be printed more concisely as
<P><pre>
#3A((&quot;stop&quot; &quot;spot&quot;) (&quot;post&quot; &quot;pots&quot;) (&quot;tops&quot; &quot;opts&quot;))
</pre><P>
</dl>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif">
<dl compact><dd>
If <tt>*print-array*</tt> is <tt>nil</tt>, then the array is printed
in a format (using <tt>#&lt;</tt>) that is concise but not readable.
</dl>
<img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<p>
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
<dl compact><dd>
X3J13 voted in June 1989 (DATA-IO) <A NAME=22348>&#160;</A> to specify that if <tt>*print-readably*</tt>
is not <tt>nil</tt> 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 <tt>*print-readably*</tt> is not <tt>nil</tt>, as if <tt>*print-level*</tt>
and <tt>*print-length*</tt> were <tt>nil</tt> and <tt>*print-array*</tt> were not <tt>nil</tt>,
regardless of their actual values.
</dl>
<img align=bottom alt="change_end" src="gif/change_end.gif">
<dl compact>
<DT><i>Random-states</i>
<DD>
Common Lisp does not specify a specific syntax
for printing objects of type <tt>random-state</tt>. 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 <tt>read</tt>
can construct from the printed representation a copy of the random-state
object as if the copy had been made by <tt>make-random-state</tt>.
</dl>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif">
<dl compact>
<DT><i>Pathnames</i>
<DD>
Common Lisp does not specify a specific syntax
for printing objects of type <tt>pathname</tt>. However, every implementation
must arrange to print a pathname in such a way that,
within the same implementation of Common Lisp, the function <tt>read</tt>
can construct from the printed representation an equivalent
instance of the pathname object.
</dl>
<img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<p>
<img align=bottom alt="change_begin" src="gif/change_begin.gif">
<dl compact><dd>
X3J13 voted in June 1989 (PATHNAME-PRINT-READ) <A NAME=22369>&#160;</A>
to specify that if <tt>*print-escape*</tt> is true, a pathname
should be printed by <tt>write</tt> as <tt>#P&quot;...&quot;</tt> where <tt>&quot;...&quot;</tt> is the
namestring representation of the pathname. If <tt>*print-escape*</tt>
is false, <tt>write</tt> prints a pathname by printing its namestring
(presumably without escape characters or surrounding double quotes).
<P>
X3J13 voted in June 1989 (DATA-IO) <A NAME=22378>&#160;</A> to specify that if <tt>*print-readably*</tt>
is not <tt>nil</tt> 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 <tt>*print-readably*</tt> is not <tt>nil</tt>, as if <tt>*print-escape*</tt>
were <tt>nil</tt>,
regardless of its actual value.
<P>
</DL>
<img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
Structures defined by <tt>defstruct</tt> are printed under the
control of the user-specified <tt>:print-function</tt> option to <tt>defstruct</tt>.
If the user does not provide a printing function explicitly,
then a default printing function is supplied that prints the structure
using <tt>#S</tt> syntax (see section <A HREF="node191.html#SHARPSIGNMACROCHARACTERSECTION">22.1.4</A>).
<P>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif"><br>
Any other types are printed in an implementation-dependent manner. It is
recommended that printed representations of all such objects begin with
the characters <tt>#&lt;</tt> and end with <tt>&gt;</tt> so that the reader will
catch such objects and not permit them to be read under normal
circumstances. It is specifically and purposely <i>not</i>
required that a Common Lisp implementation
be able to print an object of type <tt>hash-table</tt>, <tt>readtable</tt>,
<tt>package</tt>, <tt>stream</tt>, or <tt>function</tt> in a way that can be read back in
successfully by <tt>read</tt>; the use of <tt>#&lt;</tt> syntax is especially
recommended for the printing of such objects.
<br><img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in June 1989 (DATA-IO) <A NAME=22405>&#160;</A> to specify that if <tt>*print-readably*</tt>
is not <tt>nil</tt> 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 <tt>print-not-readable</tt> must be signaled to avoid
printing an unreadable syntax such as <tt>#&lt;...&gt;</tt>.
<P>
X3J13 voted in June 1989 (DATA-IO) <A NAME=22410>&#160;</A> to add
<tt>print-unreadable-object</tt>, a macro that prints an object using <tt>#&lt;...&gt;</tt>
syntax and also takes care of checking the variable <tt>*print-readably*</tt>.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
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
<tt>*print-level*</tt> and <tt>*print-length*</tt> 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.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
<BR><b>[Variable]</b><BR>
<tt>*print-readably*</tt><P>The default value of <tt>*print-readably*</tt> is
<tt>nil</tt>. If <tt>*print-readably*</tt> 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 <A HREF="node228.html#SIMILARASACONSTANTSECTION">25.1.4</A>) to the object that was printed.
<P>
If <tt>*print-readably*</tt> is true and printing a readable printed
representation is not possible, the printer signals an error of type
<tt>print-not-readable</tt> rather than using an unreadable syntax such as <tt>#&lt;</tt>.
The printed representation produced when <tt>*print-readably*</tt> is true might
or might not be the same as the printed representation produced when
<tt>*print-readably*</tt> is false.
<P>
If <tt>*print-readably*</tt> is true and another printer control variable
(such as <tt>*print-length*</tt>, <tt>*print-level*</tt>, <tt>*print-escape*</tt>, <tt>*print-gensym*</tt>,
<tt>*print-array*</tt>, or an implementation-defined printer control variable)
would cause the preceding requirements to be violated, that other
printer control variable is ignored.
<P>
The printing of interned symbols is not affected by <tt>*print-readably*</tt>.
<P>
Note that the ``similar as a constant'' rule for readable printing
implies that <tt>#A</tt> or <tt>#(</tt> syntax cannot be used for arrays of element-type
other than <tt>t</tt>. An implementation will have to use another syntax or
signal a <tt>print-not-readable</tt> error. A <tt>print-not-readable</tt> error will not
be signaled for strings or bit-vectors.
<P>
All methods for <tt>print-object</tt> must obey <tt>*print-readably*</tt>. This
rule applies to both user-defined methods and implementation-defined methods.
<P>
The reader control variable <tt>*read-eval*</tt> also affects printing.
If <tt>*read-eval*</tt> is false and <tt>*print-readably*</tt> is true, any <tt>print-object</tt>
method that would otherwise output a <tt>#.</tt> reader macro must either output something
different or signal an error of type <tt>print-not-readable</tt>.
<P>
Readable printing of structures and objects of type <tt>standard-object</tt>
is controlled
by their <tt>print-object</tt> methods, not by their <tt>make-load-form</tt> methods.
``Similarity as a constant'' for these objects is application-dependent
and hence is defined to be whatever these methods do.
<P>
<tt>*print-readably*</tt> 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.
<P>
<tt>*print-readably*</tt> is more rigorous than <tt>*print-escape*</tt>; 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.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR><b>[Variable]</b><BR>
<tt>*print-escape*</tt><P>When this flag is <tt>nil</tt>, 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 <tt>princ</tt> effectively binds <tt>*print-escape*</tt> to <tt>nil</tt>.
<P>
When this flag is not <tt>nil</tt>, then an attempt is made to print an
expression in such a way that it can be read again to produce an
<tt>equal</tt> structure.
The function <tt>prin1</tt> effectively binds <tt>*print-escape*</tt> to <tt>t</tt>.
The initial value of this variable is <tt>t</tt>.
<P>
<hr>
<b>Compatibility note:</b>
<tt>*print-escape*</tt> controls what was called <i>slashification</i>
in MacLisp.
<hr>
<P>
<BR><b>[Variable]</b><BR>
<tt>*print-pretty*</tt><P>When this flag is <tt>nil</tt>, then only a small amount of whitespace is
output when printing an expression.
<P>
When this flag is not <tt>nil</tt>, 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 <tt>'foo</tt>
instead of <tt>(quote foo)</tt>.
<P>
The initial value of <tt>*print-pretty*</tt> is implementation-dependent.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in January 1989
(PRETTY-PRINT-INTERFACE) <A NAME=22481>&#160;</A>
to adopt a facility for user-controlled pretty printing
in Common Lisp
(see chapter <A HREF="node253.html#PPRINT">27</A>).
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR><b>[Variable]</b><BR>
<tt>*print-circle*</tt><P>When this flag is <tt>nil</tt> (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.
<P>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif"><br>
When this flag is not <tt>nil</tt>, then the printer will endeavor to detect
cycles in the structure to be printed, and to use <tt>#<i>n</i>=</tt> and <tt>#<i>n</i>#</tt>
syntax to indicate the circularities.
<br><img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in June 1989 (PRINT-CIRCLE-SHARED) <A NAME=22493>&#160;</A>
to specify that if <tt>*print-circle*</tt> is true, the printer is required
to detect not only cycles but shared substructure, indicating both through the
use of <tt>#<i>n</i>=</tt> and <tt>#<i>n</i>#</tt> syntax.
As an example, under the specification of the first edition
<P><pre>
(print '(#1=(a #1#) #1#))
</pre><P>
might legitimately print <tt>(#1=(A #1#) #1#)</tt> or
<tt>(#1=(A #1#) #2=(A #2#))</tt>; the vote specifies that the first
form is required.
<P>
X3J13 voted in January 1989
(PRINT-CIRCLE-STRUCTURE) <A NAME=22503>&#160;</A>
to specify that user-defined printing functions for the <tt>defstruct</tt>
<tt>:print-function</tt> option, as well as user-defined methods for the
CLOS generic function <tt>print-object</tt>, may print objects to the
supplied stream using <tt>write</tt>, <tt>print1</tt>, <tt>princ</tt>, <tt>format</tt>,
or <tt>print-object</tt> and expect circularities to be detected and printed
using <tt>#<i>n</i>#</tt> syntax (when <tt>*print-circle*</tt> is non-<tt>nil</tt>, of course).
<P>
It seems to me that the same ought to apply to abbreviation
as controlled by <tt>*print-level*</tt> and <tt>*print-length*</tt>, but that
was not addressed by this vote.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR><b>[Variable]</b><BR>
<tt>*print-base*</tt><P>The value of <tt>*print-base*</tt> determines in what radix the printer will print
rationals. This may be any integer from <tt>2</tt> to <tt>36</tt>, inclusive;
the default value is <tt>10</tt> (decimal radix).
For radices above <tt>10</tt>, letters of the alphabet are used to represent
digits above <tt>9</tt>.
<P>
<hr>
<b>Compatibility note:</b>MacLisp calls this variable <tt>base</tt>, and its default value is <tt>8</tt>, not <tt>10</tt>.
<P>
In both MacLisp and Common Lisp,
floating-point numbers are always printed in decimal, no matter what the value
of <tt>*print-base*</tt>.
<hr>
<P>
<BR><b>[Variable]</b><BR>
<tt>*print-radix*</tt><P>If the variable <tt>*print-radix*</tt> is non-<tt>nil</tt>, 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 <tt>O</tt> with the digit <tt>0</tt>,
and of the letter <tt>B</tt> with the digit <tt>8</tt>, 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 <tt>#24rN</tt>. If <tt>*print-base*</tt>
is <tt>2</tt>, <tt>8</tt>, or <tt>16</tt>, then the radix specifier used is <tt>#b</tt>,
<tt>#o</tt>, or <tt>#x</tt>. For integers, base ten is indicated by a trailing
decimal point instead of a leading radix specifier; for ratios, however,
<tt>#10r</tt> is used. The default value of <tt>*print-radix*</tt> is <tt>nil</tt>.
<P>
<BR><b>[Variable]</b><BR>
<tt>*print-case*</tt><P>The <tt>read</tt> 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 <tt>*print-case*</tt> should be one of the keywords
<tt>:upcase</tt>, <tt>:downcase</tt>, or <tt>:capitalize</tt>;
the initial value is <tt>:upcase</tt>.
<P>
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
<tt>*print-case*</tt>. The convention for what constitutes
a ``word'' is the same as for the function <tt>string-capitalize</tt>.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in June 1989 (PRINT-CASE-PRINT-ESCAPE-INTERACTION) <A NAME=22562>&#160;</A>
to clarify the interaction of <tt>*print-case*</tt> with <tt>*print-escape*</tt>.
When <tt>*print-escape*</tt> is <tt>nil</tt>, <tt>*print-case*</tt> determines the
case in which to print all uppercase characters in the print name of the symbol.
When <tt>*print-escape*</tt> is not <tt>nil</tt>, 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 <tt> </tt>, or between multiple escape characters,
typically <tt>|</tt>); <tt>*print-case*</tt> determines the
case in which to print all uppercase characters that will not appear in an escape context.
For example, when the value of <tt>*print-case*</tt> is <tt>:upcase</tt>,
an implementation might choose to print the symbol whose print name is <tt>&quot;(S)HE&quot;</tt>
as <tt> (S )HE</tt> or as <tt>|(S)HE|</tt>, among other possibilities.
When the value of <tt>*print-case*</tt> is <tt>:downcase</tt>, the corresponding output
should be <tt> (s )he</tt> or <tt>|(S)HE|</tt>, respectively.
<P>
Consider the following test code. (For the sake of this example
assume that <tt>readtable-case</tt> is <tt>:upcase</tt> in the current readtable; this is
discussed further below.)
<P><pre>
(let ((tabwidth 11))
(dolist (sym '(|x| |FoObAr| |fOo|))
(let ((tabstop -1))
(format t &quot;~&amp;&quot;)
(dolist (escape '(t nil))
(dolist (case '(:upcase :downcase :capitalize))
(format t &quot;~VT&quot; (* (incf tabstop) tabwidth))
(write sym :escape escape :case case)))))
(format t &quot;~%&quot;))
</pre><P>
An implementation that leans heavily on multiple-escape characters (vertical bars)
might produce the following output:
<P><pre>
|x| |x| |x| x x x
|FoObAr| |FoObAr| |FoObAr| FoObAr foobar Foobar
|fOo| |fOo| |fOo| fOo foo foo
</pre><P>
An implementation that leans heavily on single-escape characters (backslashes)
might produce the following output:
<P><pre>
\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
</pre><P>
These examples are not exhaustive; output using both kinds of escape characters
(for example, <tt>|FoO|\bA\r</tt>) is permissible (though ugly).
<P>
X3J13 voted in June 1989 (READ-CASE-SENSITIVITY) <A NAME=22614>&#160;</A>
to add a new <tt>readtable-case</tt> slot to readtables to control
automatic case conversion during the reading of symbols.
The value of <tt>readtable-case</tt> in the current readtable also affects the printing
of unescaped letters (letters appearing in an escape context are always
printed in their own case).
<UL><LI> If <tt>readtable-case</tt> is <tt>:upcase</tt>, unescaped uppercase letters are printed
in the case specified by <tt>*print-case*</tt> and unescaped lowercase letters
are printed in their own case. (If <tt>*print-escape*</tt> is non-<tt>nil</tt>,
all lowercase letters will necessarily be escaped.)
<P>
<LI> If <tt>readtable-case</tt> is <tt>:downcase</tt>, unescaped lowercase letters are printed
in the case specified by <tt>*print-case*</tt> and unescaped uppercase letters
are printed in their own case. (If <tt>*print-escape*</tt> is non-<tt>nil</tt>,
all uppercase letters will necessarily be escaped.)
<P>
<LI> If <tt>readtable-case</tt> is <tt>:preserve</tt>,
all unescaped letters are printed in their own case,
regardless of the value of <tt>*print-case*</tt>. There is no
need to escape any letters, even if <tt>*print-escape*</tt> is non-<tt>nil</tt>,
though the X3J13 vote did not prohibit escaping letters in this situation.
<P>
<LI> If <tt>readtable-case</tt> is <tt>:invert</tt>,
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 <tt>:invert</tt> does not always invert the case; the inversion is conditional.)
There is no
need to escape any letters, even if <tt>*print-escape*</tt> is non-<tt>nil</tt>,
though the X3J13 vote did not prohibit escaping letters in this situation.
</UL>
Consider the following code.
<P><pre>
;;; Generate a table illustrating READTABLE-CASE and *PRINT-CASE*.
(let ((*readtable* (copy-readtable nil))
(*print-case* *print-case*))
(format t &quot;READTABLE-CASE *PRINT-CASE* Symbol-name Output~
~%------------------------------------------------~
~%&quot;)
(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 &quot;:~A~15T:~A~29T~A~42T~A~%&quot;
(string-upcase readtable-case)
(string-upcase print-case)
(symbol-name sym)
(prin1-to-string sym)))))))
</pre><P>
<P>
Note that the call to <tt>prin1-to-string</tt>
(the last argument in the call to <tt>format</tt> that is within the nested loops)
effectively uses a non-<tt>nil</tt> value for <tt>*print-escape*</tt>.
<P>
Assuming an implementation that uses vertical bars around a symbol name
if any characters need escaping,
the output from this test code should be
<P>
<P><pre>
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
</pre><P>
<P>
This illustrates all combinations for
<tt>readtable-case</tt> and <tt>*print-case*</tt>.
<P>
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR><b>[Variable]</b><BR>
<tt>*print-gensym*</tt><P>The <tt>*print-gensym*</tt> variable controls whether the prefix <tt>#:</tt>
is printed before symbols that have no home package.
The prefix is printed if the variable is not <tt>nil</tt>.
The initial value of <tt>*print-gensym*</tt> is <tt>t</tt>.
<P>
<BR><b>[Variable]</b><BR>
<tt>*print-level*</tt> <tt><BR></tt><tt>*print-length*</tt><P>The <tt>*print-level*</tt> variable controls how many levels deep a nested
data object will print.
If <tt>*print-level*</tt> is <tt>nil</tt> (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 <tt>0</tt>;
its components (as of a list or vector) are at level <tt>1</tt>; 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 <tt>*print-level*</tt>, then the object
is printed as simply <tt>#</tt>.
<P>
The <tt>*print-length*</tt> variable controls how many elements at a given level
are printed. A value of <tt>nil</tt> (the initial value) indicates that there
be no limit to the number of components printed. Otherwise, the value of
<tt>*print-length*</tt> should be an integer. Should the number of elements of a
data object exceed the value <tt>*print-length*</tt>, the printer will print three
dots, <tt>...</tt>, in place of those elements beyond the number specified
by <tt>*print-length*</tt>. (In the case of a dotted list, if the list contains
exactly as many elements as the value of <tt>*print-length*</tt>, and in addition
has the non-null atom terminating it, that terminating atom is printed
rather than the three dots.)
<P>
<tt>*print-level*</tt> and <tt>*print-length*</tt> 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.
<P>
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 <tt>#</tt> dispatch character normally signals
an error when followed by whitespace or <tt>)</tt>, and because <tt>...</tt>
is defined to be an illegal token, as are all tokens consisting
entirely of periods (other than the single dot used in dot notation).
<P>
As an example, table <A HREF="node193.html#LEVELLENGTHTABLE">22-6</A> shows the ways the object
<P><pre>
(if (member x y) (+ (car x) 3) '(foo . #(a b c d &quot;Baz&quot;)))
</pre><P>
would be printed for various values of <tt>*print-level*</tt>
(in the column labeled <i>v</i>) and <tt>*print-length*</tt> (in the column labeled <i>n</i>).
<p>
<pre>
<A NAME=LEVELLENGTHTABLE>&#160;</A>
----------------------------------------------------------------
Table 22-6: Examples of Print Level and Print Length Abbreviation
<i>v</i> <i>n</i> <i>Output</i>
======================================================
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")))
======================================================
----------------------------------------------------------------
</pre>
<P>
<BR><b>[Variable]</b><BR>
<tt>*print-array*</tt><P>If <tt>*print-array*</tt> is <tt>nil</tt>, then the contents of arrays other than strings
are never printed. Instead, arrays are printed in a concise form (using
<tt>#&lt;</tt>) that gives enough information for the user to be able to
identify the array but does not include the entire array contents.
If <tt>*print-array*</tt> is not <tt>nil</tt>, non-string arrays are printed using
<tt>#(</tt>, <tt>#*</tt>, or <tt>#<i>n</i>A</tt> syntax.
<p>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
<i>Notice of correction.</i>
In the first edition, the preceding paragraph mentioned the nonexistent
variable <tt>print-array</tt> instead of <tt>*print-array*</tt>.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
The initial value of <tt>*print-array*</tt> is implementation-dependent.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
<BR><b>[Macro]</b><BR>
<tt>with-standard-io-syntax</tt> <tt>{declaration}*</tt> <tt>{form}*</tt>
<p>
X3J13 voted in June 1989 (DATA-IO) <A NAME=22735>&#160;</A> to add the
macro <tt>with-standard-io-syntax</tt>. Within the dynamic extent of the body,
all reader/printer control<em>variables,</em> including any
implementation-defined ones not specified byCommon Lisp, are bound to
values that produce standard read/printbehavior. Table <A
HREF="node193.html#WITHSTANDARDIOSYNTAXTABLE">22-7</A> shows the values
to which standard Common Lisp <em>variables</em> are bound.
<P>
The values returned by <tt>with-standard-io-syntax</tt> are the values
of the last body <i>form</i>, or <tt>nil</tt> if there are no body forms.
<P>
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:
<P><pre>
;;; 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))))
</pre><P>
<P>
Using <tt>with-standard-io-syntax</tt> to bind all the variables,
instead of using <tt>let</tt> 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
<tt>*package*</tt> or <tt>*read-eval*</tt>, it can be bound by <tt>let</tt> inside the body of
<tt>with-standard-io-syntax</tt>. For example:
<P><pre>
;;; 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)))))
</pre><P>
Similarly, a user who dislikes the
arbitrary choice of values for <tt>*print-circle*</tt> and <tt>*print-pretty*</tt>
can bind these variables to other values inside the body.
<P>
The X3J13 vote left it unclear whether <tt>with-standard-io-syntax</tt>
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.
<P>
<pre>
<A NAME=WITHSTANDARDIOSYNTAXTABLE>&#160;</A>
----------------------------------------------------------------
Table 22-7: Standard Bindings for I/O Control Variables
Variable Value
===========================================================
*package* the <tt>common-lisp-user</tt> 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 <tt>*print-right-margin*</tt>,
<tt>*print-miser-width*</tt>, <tt>*print-lines*</tt>, and
<tt>*print-pprint-dispatch*</tt> (see section 27.2) but did not
specify the values to which <tt>with-standard-io-syntax</tt> should
bind them. I recommend that all four should be bound to <tt>nil</tt>.
----------------------------------------------------------------
</pre>
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<p>
<BR> <HR><A NAME=tex2html3949 HREF="node194.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html3947 HREF="node187.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html3943 HREF="node192.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html3951 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html3952 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html3950 HREF="node194.html"> Input Functions</A>
<B>Up:</B> <A NAME=tex2html3948 HREF="node187.html"> Printed Representation of </A>
<B> Previous:</B> <A NAME=tex2html3944 HREF="node192.html"> The Readtable</A>
<HR> <P>
<HR>
<P><ADDRESS>
AI.Repository@cs.cmu.edu
</ADDRESS>
</BODY>