1062 lines
51 KiB
HTML
1062 lines
51 KiB
HTML
|
<!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> </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> </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> </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> </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> </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 "FOO"))) (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> </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> </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>#<</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> </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>#<</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> </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><<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><<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(("stop" "spot") ("post" "pots") ("tops" "opts"))
|
||
|
</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>#<</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> </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> </A>
|
||
|
to specify that if <tt>*print-escape*</tt> is true, a pathname
|
||
|
should be printed by <tt>write</tt> as <tt>#P"..."</tt> where <tt>"..."</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> </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>#<</tt> and end with <tt>></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>#<</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> </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>#<...></tt>.
|
||
|
<P>
|
||
|
X3J13 voted in June 1989 (DATA-IO) <A NAME=22410> </A> to add
|
||
|
<tt>print-unreadable-object</tt>, a macro that prints an object using <tt>#<...></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>#<</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> </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> </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> </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> </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>"(S)HE"</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 "~&")
|
||
|
(dolist (escape '(t nil))
|
||
|
(dolist (case '(:upcase :downcase :capitalize))
|
||
|
(format t "~VT" (* (incf tabstop) tabwidth))
|
||
|
(write sym :escape escape :case case)))))
|
||
|
(format t "~%"))
|
||
|
</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> </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 "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)))))))
|
||
|
</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 "Baz")))
|
||
|
</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> </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>#<</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> </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> </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>
|