<?xml version="1.0" encoding="UTF-8"?>

<chapter id="intro"><title>Introduction
  <ulink role="clhs" url="chap-1"/></title>

<section id="spec-symb"><title>Special Symbols
  <ulink role="clhs" url="sec_1-4-1-3"/></title>

<para>The <firstterm>final delimiter
  <indexterm id="fin-delim" significance="preferred">
   <primary>final delimiter</primary></indexterm></firstterm>
 of an interactive stream:
 <variablelist><varlistentry><term>&unix;</term>
   <listitem><simpara>type <keycombo>&ctrl;<keysym>D</keysym></keycombo>
     at the beginning of a line</simpara></listitem></varlistentry>
  <varlistentry><term>&win32;</term>
   <listitem><simpara>type <keycombo>&ctrl;<keysym>Z</keysym></keycombo>,
     followed by &enter;</simpara></listitem>
 </varlistentry></variablelist>
 This final delimiter is never actually seen by programs; no need to
 test for <keysym>#\^D</keysym> or <keysym>#\^Z</keysym> - use
 &read-char-no-hang; to check for &eos;.</para>
<para>A newline character can be entered by the user by pressing the
 &enter; key.</para>
<para>See also <xref linkend="clear-input"/>.</para>
</section>


<section id="error-terms"><title>Error Terminology
  <ulink role="clhs" url="sec_1-4-2"/></title>

<para>Safety settings are ignored by the interpreted code;
 therefore where the standard uses the phrase <quote>should signal an
 error</quote>, an &err-sig;.
 See <xref linkend="safety-decl"/> for the safety of compiled code.</para>

</section>

<section id="cl-symb"><title>Symbols in the Package &cl-pac;
  <ulink role="clhs" url="sec_1-9"/></title>

<para>All 978 symbols in the &cl-pac; package specified by the
 &ansi-cl; are implemented.</para>

</section>

</chapter>

<chapter id="syntax"><title>Syntax <ulink role="clhs" url="chap-2"/></title>

<section id="std-char"><title>Standard Characters
  <ulink role="clhs" url="sec_2-1-3"/></title>

<para>The standard characters are &nl-s; and the
 <link linkend="graph-char">graphic characters</link>
 with a &code-char; between 32 and 126 (inclusive).</para>
</section>

<section id="reader-alg"><title>Reader Algorithm
  <ulink role="clhs" url="sec_2-2"/></title>

<para>The requirement of step 4 that a <quote><ulink url="clhs/glo">reader
   macro function</ulink> may return zero values or one value</quote>
 &is-e; enforced.  You can use the function &values; to control the
 number of values returned.</para>

</section>

<section id="tokens"><title>Symbols as Tokens
  <ulink role="clhs" url="sec_2-3-4"/></title>

<para>A <firstterm>reserved token
  <indexterm id="res-token" significance="preferred">
   <primary>token</primary><secondary>reserved</secondary>
 </indexterm></firstterm>,
 i.e., a <ulink url="clhs/glo">token</ulink> that has
 <ulink url="clhs/glo">potential number</ulink> syntax but cannot be
 interpreted as a &number-t;, is interpreted as &symbol-t; when being
 read.</para>

</section>

<section id="valid-patterns"><title>Valid Patterns for Tokens
  <ulink role="clhs" url="sec_2-3-5"/></title>

<para>When a token with package markers is read, then no checking is
 done whether the &symbol-package; part and the &symbol-name; part do
 not have number syntax. (What would the purpose of this check be?)
 So we consider tokens like <token>USER::</token> or <token>:1</token> or
 <token>LISP::4711</token> or <token>21:3</token> as symbols.</para>

</section>

<section id="backquote"><title>Backquote
  <ulink role="clhs" url="sec_2-4-6"/></title>

<para>The backquote read macro also works when nested. Example:
<programlisting id="bq-nested" language="lisp">
   (&eval; ``(,#'(&lambda-m; () ',a) ,#'(&lambda-m; () ',b)))
 &equiv; (&eval; `(list #'(&lambda-m; () ',a) #'(&lambda-m; () ',b)))
 &equiv; (&eval; (list 'list (list 'function (list 'lambda nil (list 'quote a)))
                     (list 'function (list 'lambda nil (list 'quote b)))))
</programlisting></para>

</section>

<section id="sharpsign"><title>Sharpsign
  <ulink role="clhs" url="sec_2-4-8"/></title>

<para>Reader macros are also defined for the following:
<variablelist id="extra-read-macro-table">
 <title>Additional reader macros</title>
 <varlistentry><term><literal role="data">#,</literal></term>
  <listitem><simpara>load-time evaluation, kept despite the &ansi-cl;
    issue &iss315;.</simpara></listitem></varlistentry>
 <varlistentry><term><literal role="data">#Y</literal></term>
  <listitem><simpara>compiled &function-t; objects and &in-s;'s &encoding;s
 </simpara></listitem></varlistentry>
 <varlistentry><term><literal role="data">#&quot;&quot;</literal></term>
  <listitem><simpara>&pathname-t;: <filename>#"test.lisp"</filename>
   is the value of <code>(&pathname; "test.lisp")</code></simpara>
 </listitem></varlistentry>
</variablelist></para>

<section id="sharpsign-backslash"><title>Sharpsign Backslash
  <ulink role="clhs" url="sec_2-4-8-1"/></title>

<para><keysym>#\Code</keysym> allows input of characters of arbitrary code:
 e.g., <keysym>#\Code231</keysym> reads as the character
 <code>(&code-char; 231)</code>.</para>

</section>

<section id="sharpsign-less-than"><title>Sharpsign Less-Than-Sign
  <ulink role="clhs" url="sec_2-4-8-20"/></title>

<para>This is the list of objects whose external representation cannot
 be meaningfully read in:<variablelist id="unreadable-objects">
  <title>Unreadable objects</title>
<varlistentry><term><literal role="#lt">&type-r; ...</literal></term>
 <listitem><simpara>all &structure-object-t;s lacking a keyword
   constructor</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">ARRAY &type-r;
   &dimensions-r;</literal></term>
 <listitem><simpara>all &array-t;s except &string-t;s, if
   &print-array-var; is &nil;</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">SYSTEM-FUNCTION &name-r;</literal></term>
 <listitem><simpara>built-in function written in &c-lang;
</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">ADD-ON-SYSTEM-FUNCTION
   &name-r;</literal></term>
 <listitem><simpara>&module; function written in &c-lang;
</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">SPECIAL-OPERATOR
   &name-r;</literal></term>
 <listitem><simpara>special operator handler</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">COMPILED-FUNCTION
   &name-r;</literal></term>
 <listitem><simpara>compiled function, if &pr-closure; is &nil;
</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">FUNCTION &name-r; ...</literal></term>
 <listitem><simpara>interpreted function, , if &pr-closure; is &nil;
</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">FRAME-POINTER #x...</literal></term>
 <listitem><simpara>pointer to a stack frame</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">DISABLED POINTER</literal></term>
 <listitem><simpara>frame pointer which has become invalid on exit from the
   corresponding &block; or &tagbody;</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">...STREAM...</literal></term>
 <listitem><simpara>&stream-t;</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">PACKAGE &name-r;</literal></term>
 <listitem><simpara>&package-t;</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">HASH-TABLE #x...</literal></term>
 <listitem><simpara>&hash-table-t;, if &print-array-var; is &nil;
</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">READTABLE #x...</literal></term>
 <listitem><simpara>&readtable-t;</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">SYMBOL-MACRO &form-r;</literal></term>
 <listitem><simpara>&symbol-macro; handler</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">MACRO &func-r;</literal></term>
 <listitem><simpara>macro expander (defined by &defmacro; and friends)
</simpara></listitem></varlistentry>
<!-- #ifdef FOREIGN -->
<varlistentry><term><literal role="#lt">&foreign-pointer-t;
   #x...</literal></term>
 <listitem><simpara>foreign pointer (&unix-w32-only;)
</simpara></listitem></varlistentry>
<!-- #endif -->
<!-- #ifdef DYNAMIC_FFI -->
<varlistentry><term><literal role="#lt">&foreign-address-t;
   #x...</literal></term>
 <listitem><simpara>foreign address
   (&unix-w32-only;)</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">&foreign-variable-t; &name-r;
   #x...</literal></term>
 <listitem><simpara>foreign variable (&unix-w32-only;)
</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">&foreign-function-t; &name-r;
   #x...</literal></term>
 <listitem><simpara>foreign function (&unix-w32-only;)
</simpara></listitem></varlistentry>
<!-- #endif -->
<varlistentry><term><literal role="#lt">UNBOUND</literal></term>
 <listitem><simpara><quote>value</quote> of an unbound symbol, an unsupplied
   optional or keyword argument</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">SPECIAL REFERENCE</literal></term>
 <listitem><simpara>environment marker for variables declared &special-dec;
</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">DOT</literal></term>
 <listitem><simpara>internal &read; result for <quote>.</quote>
</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">END OF FILE</literal></term>
 <listitem><simpara>internal &read; result, when the &eos; is reached
</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">READ-LABEL ...</literal></term>
 <listitem><simpara>intermediate &read; result for &sharp-sharp;
</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">ADDRESS #x...</literal></term>
 <listitem><simpara>machine address, should not occur
</simpara></listitem></varlistentry>
<varlistentry><term><literal role="#lt">SYSTEM-POINTER #x...</literal></term>
 <listitem><simpara>should not occur</simpara></listitem></varlistentry>
</variablelist></para>
</section>

</section>
</chapter>


<chapter id="eval"><title>Evaluation and Compilation
  <ulink role="clhs" url="chap-3"/></title>

<para>All the functions built by &function;, &compile; and the like are
 atoms.  There are built-in functions written in &c-lang;, compiled
 functions (both of type &compiled-function-t;) and interpreted
 functions (of type &function-t;).</para>

<table id="eval-limits-table" frame="all"><title>Function call limits</title>
 <tgroup cols="2" colsep="1" rowsep="1" align="center"><tbody>
   <row><entry>&call-arguments-limit;</entry>
    <entry>2<superscript>12</superscript>=4096</entry></row>
   <row><entry>&multiple-values-limit;</entry>
    <entry>2<superscript>7</superscript>=128</entry></row>
   <row><entry>&lambda-parameters-limit;</entry>
    <entry>2<superscript>12</superscript>=4096</entry></row>
</tbody></tgroup></table>

<section id="evaluation"><title>Evaluation
  <ulink role="clhs" url="sec_3-1"/></title>

<section id="eval-environ"><title>Introduction to Environments
  <ulink role="clhs" url="sec_3-1-1"/></title>

<formalpara id="the-env"><title>Macro &the-env;</title>
<para>As in Scheme, the macro <code>(&the-env;)</code>
 returns the current &lex-env;.  This works only in interpreted code and
 is not compilable!</para></formalpara>

<formalpara id="eval-env"><title>Function <code>(EXT:EVAL-ENV
 &form-r; &optional-amp; &env-r;)</code></title>
<para>evaluates a form in a given &lex-env;, just as if the
 form had been a part of the program that the &env-r; came from.
</para></formalpara>

</section>

<section id="sym-forms"><title>Symbols as Forms
  <ulink role="clhs" url="sec_3-1-2-1-1"/></title>

<section id="def-sym-mac"><title>Macro &define-symbol-macro;</title>

<para>The macro &define-symbol-macro; establishes &symbol-macro;s with
 global scope (as opposed to &symbol-macro;s defined with
 &symbol-macrolet;, which have local scope).</para>

<para>The function
 <firstterm>&symbol-mex;<indexterm id="symbol-mex" significance="preferred">
   <primary>SYMBOL-MACRO-EXPAND</primary></indexterm></firstterm>
 tests for a &symbol-macro;: If &symbol-r; is defined as a &symbol-macro;
 in the &glo-env;, <code>(&symbol-mex; &symbol-r;)</code> returns two
 values, &t; and the expansion; otherwise it returns &nil;.</para>

<para>&symbol-mex; is a special case of &macroexpand-1;. &macroexpand-1;
 can also test whether a symbol is defined as a &symbol-macro; in &lex-env;s
 other than the &glo-env;.</para>

</section>

<section id="dyn-var"><title>Dynamic Variables
  <ulink role="clhs" url="sec_3-1-2-1-1-2"/></title>

<para><quote>Undefined variables</quote>, i.e. &variable;s which are
 referenced outside any lexical binding for a variable of the same name
 and which are not declared &special-dec;, are treated like &dyn-var;s
 in the &glo-env;.  The compiler &signal;s a &warning-t; when it
 encounters an undefined variable.</para></section>

</section>

<section id="cons-forms"><title>Conses as Forms
  <ulink role="clhs" url="sec_3-1-2-1-2"/></title>

<para>Lists of the form <code>((&setf; &symbol-r;) ...)</code> are also
 treated as function forms. This makes the syntax
 <code>(&funcname-r; &args-r; ...)</code> consistent with the syntax
 <code>(&funcall; #'&funcname-r; &args-r; ...)</code>.
 It implements the item 7 of the &ansi-cl; issue &iss174; and the
 definition of <ulink url="clhs/glo">function form</ulink>s,
 and is consistent with the use of &funname;s elsewhere in &cl;.
</para></section>

<section id="specforms"><title>Special Forms
  <ulink role="clhs" url="sec_3-1-2-1-2-1"/></title>

<section id="eval-when"><title>Special operator &eval-when;</title>

<para>&eval-when; also accepts the situations <code>(NOT EVAL)</code>
 and <code>(NOT COMPILE)</code>.</para>

<warning><para>The situations <constant>EVAL</constant>,
 <constant>LOAD</constant> and <constant>COMPILE</constant> are
 deprecated by the &ansi-cl;, and they are &not-e; equivalent to the new
 standard situations <constant>:EXECUTE</constant>,
 <constant>:LOAD-TOPLEVEL</constant>
 and <constant>:COMPILE-TOPLEVEL</constant> in that they ignore the
 &top-level-form; versus non-&top-level-form; distinction.</para></warning>
</section>

<section id="speop-the"><title>Special operator &the;</title>

<para>The special form <code>(&the; &val-type-r; &form-r;)</code> is
 similar to &check-type; but does a type check only in interpreted
 code (no type check is done in compiled code - but see the &ethe;
 macro) and does not allow interactive error correction by the user.
</para></section>
</section>

<section id="funforms"><title>Function Forms
  <ulink role="clhs" url="sec_3-1-2-1-2-3"/></title>

<formalpara><title>Constant &lambda-list-keywords;</title>
<para><code>(&optional-amp; &rest-amp; &key-amp; &allow-other-keys-amp;
  &aux-amp; &body-amp; &whole-amp; &environment-amp;)</code></para></formalpara>

<section id="sym-fun"><title>Function &symbol-function;</title>

<para><code>(&setf; (&symbol-function; &symbol-r;) &object-r;)</code>
 requires &object-r; to be either a &function-t;, a &symbol-function;
 return value, or a &lambda-expr;.  The &lambda-expr; is thereby
 immediately converted to a &function-t;.</para></section>
</section>

<section id="defun"><title>Macros &defun; &amp; &defmacro;</title>

<para>&defun; and &defmacro; are allowed in non-toplevel positions. As
 an example, consider the old (&cltl1;) definition of &gensym;:</para>

<programlisting language="lisp">
(let ((gensym-prefix "G")
      (gensym-count 1))
  (defun gensym (&amp;optional (x nil s))
    (when s
      (cond ((stringp x) (setq gensym-prefix x))
            ((integerp x)
             (if (minusp x)
               (error "~S: index ~S is negative" 'gensym x)
               (setq gensym-count x)))
            (t (error "~S: argument ~S of wrong type" 'gensym x))))
    (prog1
      (make-symbol
        (concatenate 'string
          gensym-prefix
          (write-to-string gensym-count :base 10 :radix nil)))
      (incf gensym-count))))
</programlisting>

<para>See also <xref linkend="minimal-compilation"/>.</para>

<formalpara id="arglist"><title>Function &arglist;</title>
<para>Function <code>(&arglist; &name-r;)</code> returns the &lalist; of
 the function or macro that &name-r; names and &sig-err; if &name-r; is
 not &fboundp;.  It also &sig-err; when the macro &lalist; is not
 available due to the compiler optimization settings
 (see <xref linkend="space-decl"/>).</para></formalpara>

<formalpara id="suppress-check-redef">
 <title>Variable &suppress-check-redef;</title>
<para>When <firstterm>&suppress-check-redef;</firstterm> is &nil;,
 &clisp; issues a &style-warning-t; when a function (macro, variable, class,
 etc) is redefined in a different file than its original definition.
 It is &not-e; a good idea to set this variable to &t;.
</para></formalpara>

<formalpara id="defun-accept-spelalist">
 <title>Variable &defun-accept-spelalist;</title>
<para>When <firstterm>&defun-accept-spelalist;</firstterm> is
non-&nil;, &defun; accepts &spelalist;s, converting type-parameter
associations to type declarations:
<programlisting language="lisp">(defun f ((x list) (y integer)) ...)</programlisting>
is equivalent to
<programlisting language="lisp">(defun f (x y) (declare (type list x) (type integer y)) ...)</programlisting>
This extension is disabled by &opt-ansi; and by setting &ansi; to &t;,
but can be re-enabled by setting &defun-accept-spelalist; explicitly.
</para></formalpara>

</section>

</section>

<section id="compilation"><title>Compilation
  <ulink role="clhs" url="sec_3-2"/></title>

<section id="compiler-terms"><title>Compiler Terminology
  <ulink role="clhs" url="sec_3-2-1"/></title>

<para>&clisp; compiles to platform-independent &bytecode;.</para>

<section id="compile-jit"><title>Just-In-Time Native Compilation</title>
 <subtitle><emphasis role="plat-dep">Only in &clisp; built &with;
   &lightning;</emphasis></subtitle>
<para>The code compiled to &bytecode;s with optimization levels
 <programlisting language="lisp">
(&or-m; (&geq; 0 &space-dec;) (&leq; 1 &speed-dec;))</programlisting>
 (by &compile;, &compile-file-my;, or &compile-decl;) will be
 <emphasis>just-in-time</emphasis> (i.e., on the first execution)
 compiled to native code using &lightning;.
</para>
</section>

</section>

<section id="compilation-semantics"><title>Compilation Semantics
  <ulink role="clhs" url="sec_3-2-2"/></title>

<section id="compiler-macros"><title>Compiler Macros
  <ulink role="clhs" url="sec_3-2-2-1"/></title>

<para>Compiler macros are expanded in the compiled code only, and
ignored by the interpreter.</para>

</section>

<section id="minimal-compilation"><title>Minimal Compilation
  <ulink role="clhs" url="sec_3-2-2-2"/></title>

<para>When a &defun; form is &eval;uated, the macros used there are
 expanded, so they must be already defined, and their (re)definition
 does &not-e; affect functions which are already defined.</para>

<para>This means that even the interpreted code is <emphasis>minimally
  compiled</emphasis> in &clisp;.</para>

</section>

<section id="semantic-constraints"><title>Semantic Constraints
  <ulink role="clhs" url="sec_3-2-2-3"/></title>

<para>Non-conforming code that does not follow the rule
 <blockquote><simpara><quote>Special proclamations for dynamic variables must
    be made in the compilation environment.</quote></simpara></blockquote>
 can produce quite unexpected results, e.g., observable differences
 between <emphasis>compiled</emphasis> and <emphasis>interpreted</emphasis>
 programs:<programlisting language="lisp">
(defun adder-c (value) (declare &compile-decl;) (lambda (x) (+ x value)))
<computeroutput>ADDER-C</computeroutput><lineannotation>compiled function; &value-r; is lexical</lineannotation>
(defun adder-i (value) (lambda (x) (+ x value)))
<computeroutput>ADDER-I</computeroutput><lineannotation>interpreted function; &value-r; is lexical</lineannotation>
(defparameter add-c-10 (adder-c 10))
<computeroutput>ADD-C-10</computeroutput><lineannotation>compiled function</lineannotation>
(defparameter add-i-10 (adder-i 10))
<computeroutput>ADD-I-10</computeroutput><lineannotation>interpreted function</lineannotation>
(funcall add-c-10 32)
<computeroutput>42</computeroutput><lineannotation>as expected</lineannotation>
(funcall add-i-10 32)
<computeroutput>42</computeroutput><lineannotation>as expected</lineannotation>
(defvar value 12)
<computeroutput>VALUE</computeroutput><lineannotation>affects <function>ADDER-I</function> and <function>ADD-I-10</function> but &not-e; <function>ADDER-C</function> and <function>ADD-C-10</function></lineannotation>
(funcall add-c-10 32)
<computeroutput>42</computeroutput><lineannotation>as before</lineannotation>
(funcall add-i-10 32)
<computeroutput>44</computeroutput><lineannotation>&value-r; is now dynamic!</lineannotation>
</programlisting></para>

<formalpara id="semantic-constraints-non-conf"><title>Non-conformance</title>
<para>The code shown above has a &special-dec; proclamation (by &defvar;)
 for the variable &value-r; in the execution environment
 (before the last two &funcall;s)
 but not in the compilation environment: at the moment
 the <function>ADDER-I</function> function is defined,
 &value-r; is not known to be a &special-dec; variable.
 Therefore the code is not conforming.</para></formalpara>

<simplesect id="semantic-constraints-rationale"><title>Rationale</title>
<para>The function <function>ADD-C-10</function> was compiled &before-e;
 &value-r; was declared &special-dec;, so the symbol &value-r; was
 eliminated from its code and the &special-dec; declaration did
 not affect the return value (i.e., <code>(funcall
  add-c-10 32)</code> always returned <returnvalue>42</returnvalue>).</para>
<para>On the opposite, function <function>ADDER-I</function> was &not-e;
 compiled, so <function>ADD-I-10</function>
 was <emphasis>interpreted</emphasis>.
 Whenever <function>ADD-I-10</function> is executed, its definition is
 interpreted all over again.  Before &defvar;, &value-r; is evaluated as
 a lexical (because it is &not-e; declared &special-dec; yet), but after
 &defvar;, we see a globally &special-dec; symbol &value-r; which
 can have only a global &symbol-value; (not a local binding), and thus
 we are compelled to evaluate it to <returnvalue>12</returnvalue>.</para>
<para>This behavior was implemented intentionally to ease interactive
 development, because <emphasis>usually</emphasis>
 the <function>ADDER-I</function> above would be followed by a
 (forgotten) &defvar;.</para>
<para>When a user compiles a program, the compiler is allowed to
 remember the information whether a variable was &special-dec; or not,
 because that allows the compiler to generate more efficient code,
 but in interpreted code, when the user changes the state of a variable,
 he does &not-e; want to re-evaluate all &defun;s that use the variable.</para>
<para>&ansi-cl; gives the implementation freedom regarding
 interpreted evaluation, how much it wants to remember / cache, and how
 much it wants to re-evaluate according the current &environment;,
 if it has changed. &clisp; implements <emphasis>ad-hoc
  look-up</emphasis> for variables (but &not-e; for macros, see
 <xref linkend="minimal-compilation"/>).</para>
</simplesect>

</section>
</section>

<section id="similarity"><title>Definition of Similarity
  <ulink role="clhs" url="sec_3-2-4-2-2"/></title>

<para>Hash tables are &ext-obj;s.</para>

</section>

<section id="compile-errors"><title>Exceptional Situations in the Compiler
  <ulink role="clhs" url="sec_3-2-5"/></title>

<para>Both &compile; and &eval; may &signal; the &source-program-error;
 &condition-t; which derives from &program-error-t; and which contains
 additional slots with accessors <variablelist>
<varlistentry><term>&source-program-error-form;</term>
 <listitem><simpara>Returns the whole form in which the &error-t; was
   &signal;ed</simpara></listitem></varlistentry>
<varlistentry><term>&source-program-error-detail;</term>
 <listitem><simpara>Returns the specific (usually small) part of the
   above which triggered the &error-t;</simpara></listitem></varlistentry>
</variablelist></para>

<formalpara id="key-optional"><title>Mixing &optional-amp; and &key-amp;</title>
<para>It is a bad design to have both &optional-amp; and &key-amp; in the
same &lalist;, especially if the number of optional arguments is even:
the users will often forget to supply optional arguments when supplying
keys, e.g., <code>(&read-from-string; &string-r; &start-k; 5)</code>
instead of <code>(&read-from-string; &string-r; t nil &start-k; 5)</code>.
This is why the &clisp; compiler issues a &style-warning-t; in such cases:
<programlisting>(&defun; foo (&optional-amp; a &key-amp; b) (cons a b))
(&compile; 'foo)
WARNING: in FOO : Mixing &optional-amp; and &key-amp; in lambda list (&optional-amp; A &key-amp; B) is bad design
FOO ;
1 ;
NIL
</programlisting></para></formalpara>

</section>

</section>

<section id="declarations"><title>Declarations
  <ulink role="clhs" url="sec_3-3"/></title>

<para>The declarations <code>(&type-dec; &type-r; &var-r; ...)</code>,
 <code>(&ftype-dec; &type-r; &func-r; ...)</code>,
   are ignored by both the interpreter and the compiler.</para>

<section id="spec-decl"><title>Declaration &special-dec;</title>

<formalpara id="notspec-decl"><title>Declaration &notspec;</title>
<para>Declarations <code>(&proclaim; '(&special-dec; &var-r;))</code>
 and &defconstant; are undone by the <code>(&proclaim; '(&notspec;
  &var-r;))</code> declaration.  This declaration can be used only in
 global &proclaim; and &declaim; forms, &not-e; in local &declare; forms.
<warning><simpara>You cannot expect miracles: functions compiled &before-e;
 the &notspec; proclamation was issued will still be treating &var-r; as
 special even after the &notspec; proclamation. See also
 <xref linkend="semantic-constraints"/>.</simpara></warning></para></formalpara>

<formalpara id="spe-var-p"><title>Function &spe-var-p;</title>
<para>You can use the function <code>(&spe-var-p; &symbol-r;
  &optional-amp; &env-r;)</code> to check whether the &symbol-r; is a
 &dyn-var;.  &env-r; of &nil; or omitted means use the &glo-env;.
 You can also obtain the current &lex-env; using the macro
 &the-env; (interpreted code only).
 This function will always return &t; for global special
 variables and &constant;s.</para></formalpara>
</section>

<section id="constant-notinline"><title>Declaration &constnotin;</title>
 <para>Constants defined by &defconstant; but proclaimed &constnotin;
  will not be inlined by the compiler. This is useful for variables
  which remain constant within an a single Lisp process but may vary
  between processes and machines (such as endianness or word size) thus
  they should be written to &fasl-file;s as symbols, not values.
</para></section>

<section id="constantp"><title>Function &constantp;</title>

<para>Function &constantp; fully complies with &ansi-cl;.
Additionally, some non-trivial forms are identified as constants, e.g.,
<code>(&constantp; '(&plus; 1 2 3))</code> returns &t;.</para>

<warning><para>Since &defconstant; initial value forms are not
evaluated at compile time, &constantp; will not report &t; of their
name within the same &comp-unit; for the null &lex-env;.
This is consistent and matches questionable code using the pattern
<code>(&if; (&constantp; &form-r;) (&eval; &form-r;))</code>.
Use &eval-when; if you need recognition and the value during
compile-time. See also <xref linkend="compile-time-value"/>.
</para></warning></section>

<section id="safety-decl"><title>Declaration &safety-dec;</title>
<para>Declaration <code>(&optimize-dec; (&safety-dec; 3))</code>
 results in <quote>safe</quote> compiled code: function calls are never
 eliminated. This guarantees the semantics described in
 <ulink role="clhs" url="sec_3-5"/>.
</para></section>

<section id="compile-decl"><title>Declaration &compile-decl;</title>

<para>The declaration &compile-decl; has the effect that the current
 form is compiled prior to execution.  Examples:
<programlisting language="lisp">
(&locally; (&declare; (compile)) &form-r;)</programlisting>
executes the compiled version of &form-r;.<programlisting language="lisp">
(&let; ((x 0))
  (&flet; ((inc () (&declare; (compile)) (&incf; x))
         (dec () (&decf; x)))
    (&values; #'inc #'dec)))</programlisting>
 returns two functions.  The first is compiled and increments &x-r;, the
 second is interpreted (slower) and decrements the same &x-r;.</para>

<para>This declaration can also be used to name the resulting compiled closure:
<programlisting language="lisp">
(&lambda-m; (x) (&declare; (compile ident)) x)
<computeroutput>&sharp-lt;&compiled-function-t; IDENT&gt;</computeroutput>
(&function-lambda-expression; &star-var;)
<computeroutput>&nil;</computeroutput><lineannotation>source is not preserved</lineannotation>
<computeroutput>&t;</computeroutput>
<computeroutput>IDENT</computeroutput>
(&fboundp; 'ident)
<computeroutput>&nil;</computeroutput><lineannotation>sic!</lineannotation>
</programlisting></para>

<note><para>The declaration &compile-decl; is ignored by the following
  <ulink url="clhs/glo">special operator</ulink>s:
  <simplelist><member>&labels;</member><member>&flet;</member>
   <member>&macrolet;</member></simplelist></para></note>
</section>

<section id="space-decl"><title>Declaration &space-dec;</title>
<para>The declaration determines what metadata is recorded in the
 function object:<variablelist>
  <varlistentry><term>&space-dec; &geq; 2</term>
   <listitem><simpara>documentation string is discarded
  </simpara></listitem></varlistentry>
  <varlistentry><term>&space-dec; &geq; 3</term>
   <listitem><simpara>the original &lalist; is also discarded (most
     information is still available, see &describe-my;, but the names of
     the positional arguments are not).</simpara></listitem></varlistentry>
</variablelist></para></section>

</section>

<section id="lalist"><title>Lambda Lists
  <ulink role="clhs" url="sec_3-4"/></title>

<section id="boa-lalist"><title>Boa Lambda Lists
  <ulink role="clhs" url="sec_3-4-6"/></title>

<para>The initial value of an &aux-amp; variable in a boa &lalist; is
 the value of the corresponding slot's initial form.</para>

</section>
</section>

</chapter>


<chapter id="types-classes"><title>Types and Classes
  <ulink role="clhs" url="chap-4"/></title>

<section id="types"><title>Types <ulink role="clhs" url="sec_4-2"/></title>

<section id="type-spec"><title>Type Specifiers
  <ulink role="clhs" url="sec_4-2-3"/></title>

<para>The general form of the &complex-t; &typespec-glo; is <literal
 role="type">(&complex-t; <replaceable>type-of-real-part</replaceable>
 <replaceable>type-of-imaginary-part</replaceable>)</literal>.
 The &typespec-glo; <literal role="type">(&complex-t; &type-r;)</literal>
 is equivalent to <literal role="type">(&complex-t; &type-r;
 &type-r;)</literal>.</para>

<para>&deftype; &lalist;s are subject to destructuring (nested &lalist;s
 are allowed, as in &defmacro;) and may contain a &whole-amp; marker,
 but not an &environment-amp; marker.</para>

<formalpara><title>Function <code>(<function>EXT:TYPE-EXPAND</function>
   &type-r; &optional-amp; <replaceable>once-p</replaceable>)</code></title>
<para>If &type-r; is a user-defined &typespec-glo; this will expand it
 recursively until it is no longer a user-defined type
 (unless <replaceable>once-p</replaceable> is supplied and non-&nil;).
 Two values are returned - the expansion and an indicator (&t; or &nil;)
 of whether the original &type-r; was a user-defined &typespec-glo;.
</para></formalpara>

<itemizedlist><title>The possible results of &type-of;</title>
 <listitem><simpara>&cons-t;</simpara></listitem>
 <listitem><simpara>&symbol-t;, &null-t;, &boolean-t;,
  &keyword-t;</simpara></listitem>
 <listitem><simpara>&bit-t;, <literal role="type">(&integer-t; 0
    &sharp-dot;&most-positive-fixnum;)</literal>,
   <literal role="type">(&integer-t;
    &sharp-dot;&most-negative-fixnum; (0))</literal>,
   <literal role="type">(&integer-t;
    (&sharp-dot;&most-positive-fixnum;))</literal>,
   <literal role="type">(&integer-t; *
    (&sharp-dot;&most-negative-fixnum;))</literal></simpara></listitem>
 <listitem><simpara>&rational-t;, &short-float-t;, &single-float-t;,
   &double-float-t;, &long-float-t;, &complex-t;</simpara></listitem>
 <listitem><simpara>&character-t;, &base-char-t;,
   &standard-char-t;</simpara></listitem>
 <listitem><simpara><literal role="type">(&array-t; &eltype-r;
    &dimensions-r;)</literal>, <literal role="type">(&simple-array-t;
    &eltype-r; &dimensions-r;)</literal></simpara></listitem>
 <listitem><simpara><literal role="type">(&vector-t; &t;
    &size-r;)</literal>, <literal role="type">(&simple-vector-t;
    &size-r;)</literal></simpara></listitem>
 <listitem><simpara><literal role="type">(&string-t;
    &size-r;)</literal>, <literal role="type">(&simple-string-t;
    &size-r;)</literal></simpara></listitem>
 <listitem><simpara><literal role="type">(&base-string-t;
    &size-r;)</literal>, <literal role="type">(&simple-base-string-t;
    &size-r;)</literal></simpara></listitem>
 <listitem><simpara><literal role="type">(&bit-vector-t;
    &size-r;)</literal>, <literal role="type">(&simple-bit-vector-t;
    &size-r;)</literal></simpara></listitem>
 <listitem><simpara>&function-t;, &compiled-function-t;,
   &standard-generic-function-t;</simpara></listitem>
 <listitem><simpara>&stream-t;, &file-stream-t;, &synonym-stream-t;,
   &broadcast-stream-t;, &concatenated-stream-t;, &two-way-stream-t;,
   &echo-stream-t;, &string-stream-t;</simpara></listitem>
 <listitem><simpara>&package-t;, &hash-table-t;, &readtable-t;, &pathname-t;,
   &logical-pathname-t;, &random-state-t;, &byte-t;</simpara></listitem>
 <listitem><simpara><classname>SPECIAL-OPERATOR</classname>,
   <classname>LOAD-TIME-EVAL</classname>, &symbol-macro;,
   <classname>GLOBAL-SYMBOL-MACRO</classname>, &encoding;,
   &foreign-pointer-t;, &foreign-address-t;, &foreign-variable-t;,
   &foreign-function-t;</simpara></listitem>
 <listitem><simpara>&weak-pointer;, &weak-list;, &weak-and-relation;,
   &weak-or-relation;, &weak-mapping;, &weak-and-mapping;,
   &weak-or-mapping;, &weak-alist;,
   <link linkend="reader"><classname>READ-LABEL</classname></link>,
   <link linkend="reader"><classname>FRAME-POINTER</classname></link>,
   <classname>SYSTEM-INTERNAL</classname></simpara></listitem>
 <listitem><simpara><classname>ADDRESS</classname> (should not
  occur)</simpara></listitem>
 <listitem><simpara>any other &symbol-t; (structure types or &clos;
  classes)</simpara></listitem>
 <listitem><simpara>a class object (&clos; classes without a
   &proper-name-glo;)</simpara></listitem>
</itemizedlist>

<formalpara id="fixnum-char-ansi"><title>Function &coerce;</title>
<para>&fixnum-t; is not a <ulink url="clhs/glo">character
  designator</ulink> in &ansi-cl;, although &code-char; provides an
  obvious venue to &coerce; a &fixnum-t; to a &character-t;.
  When &fixnum-char-ansi; is &nil;, &clisp; &coerce;s &fixnum-t;s to
  &character-t;s via &code-char;.
  When &fixnum-char-ansi; is non-&nil;, &fixnum-t;s cannot be
  &coerce;d to &character-t;s.</para></formalpara>

</section>
</section>

<section id="classes"><title>Classes
  <ulink role="clhs" url="sec_4-3"/></title>

<para>The &clos; symbols are &export;ed from the package &clos-pac;.
 &cl-pac; uses (as in &use-package;) &clos-pac; and &re-export;s the
 &ansi-cl; standard exported symbols (the &clisp; extensions, e.g.,
 those described in <xref linkend="mop-chap"/>, are &not-e; &re-export;ed).
 Since <link linkend="make-pack">the default &use-k; argument</link>
 to &make-package; is &cl-pac;, the standard &clos; symbols are normally
 visible in all user-defined packages.
 If you do not want them (for example, if you want to use the
 <ulink url="ftp://ftp.gnu.org/pub/gnu/clisp/packages/pcl.sept92f.clisp.tar.gz">PCL</ulink>
 implementation of &clos; instead of the native one), do the following:
<programlisting language="lisp">
(&defpackage; "CL-NO-CLOS" (:use "CL"))
(&do-external-symbols; (&symbol-r; &cl-pac;)
  (&shadow; &symbol-r; "CL-NO-CLOS"))
(&do-symbols; (&symbol-r; "CL-NO-CLOS")
  (&export; &symbol-r; "CL-NO-CLOS"))
(&in-package; "CL-NO-CLOS")
(&load-my; "pcl")<lineannotation>or whatever</lineannotation>
(&defpackage; "MY-USER" (:use "CL-NO-CLOS"))
(&in-package; "MY-USER")
;; your code which uses PCL goes here
</programlisting></para>

</section>

<section id="clos-diff"><title>Deviations from &ansi-cl;</title>

<para>&defclass; supports the option &metaclass-k; &structure-class;.
 This option is necessary in order to define a subclass of a
 &defstruct;-defined structure type using &defclass; instead of
 &defstruct;.</para>

<para>When &call-next-method; is called with arguments, the rule that
 the ordered set of applicable methods must be the same as for the
 original arguments is enforced by the implementation only in
 interpreted code.</para>

<para><firstterm>&gen-flet;<indexterm id="gen-flet" significance="preferred">
   <primary>GENERIC-FLET</primary></indexterm></firstterm> and
 <firstterm>&gen-labels;<indexterm id="gen-labels" significance="preferred">
   <primary>GENERIC-LABELS</primary></indexterm></firstterm>
 are implemented as macros, not as special operators (as permitted by
 <ulink role="clhs" url="sec_3-1-2-1-2-2"/>).
 They are not imported into the packages &clu-pac; and &cl-pac; because
 of the &ansi-cl; issue &iss181;.</para>

<para>&print-object; is only called on objects of type
 &standard-object-t; and &structure-object-t;.
 It is not called on other objects, like &cons-t;es
 and &number-t;s, due to the performance concerns.</para>

</section>

<section id="metaclasses"><title>Standard Metaclasses
  <ulink role="clhs" url="sec_4-3-1-1"/></title>

<para>Among those classes listed in <ulink
 url="&clhs;/Body/sec_4-3-7.html#classtypecorrespondence">Figure
 4-8</ulink>, only the following are instances of &built-in-class;:
<itemizedlist>
 <listitem><simpara>&t-t;</simpara></listitem>
 <listitem><simpara>&character-t;</simpara></listitem>
 <listitem><simpara>&number-t;, &complex-t;, &real-t;, &float-t;,
   &rational-t;, &ratio-t;, &integer-t;</simpara></listitem>
 <listitem><simpara>&sequence-t;</simpara></listitem>
 <listitem><simpara>&array-t;, &vector-t;, &bit-vector-t;,
   &string-t;</simpara></listitem>
 <listitem><simpara>&list-t;, &cons-t;</simpara></listitem>
 <listitem><simpara>&symbol-t;, &null-t;</simpara></listitem>
 <listitem><simpara>&function-t;</simpara></listitem>
 <listitem><simpara>&hash-table-t;</simpara></listitem>
 <listitem><simpara>&package-t;</simpara></listitem>
 <listitem><simpara>&pathname-t;, &logical-pathname-t;</simpara></listitem>
 <listitem><simpara>&random-state-t;</simpara></listitem>
 <listitem><simpara>&readtable-t;</simpara></listitem>
 <listitem><simpara>&stream-t;, &broadcast-stream-t;,
   &concatenated-stream-t;, &echo-stream-t;, &string-stream-t;,
   &file-stream-t;, &synonym-stream-t;, &two-way-stream-t;
 </simpara></listitem>
</itemizedlist></para>

</section>

<section id="def-class"><title>Defining Classes
  <ulink role="clhs" url="sec_4-3-2"/></title>

<para>&defclass; supports the &metaclass-k; option.  Possible values are
 &standard-class; (the default), &structure-class; (which creates
 structure classes, like &defstruct; does), and user-defined
 meta-classes (see <xref linkend="validate-superclass"/>).</para>

<para>It is &not-e; required that the superclasses of a class are
 defined before the &defclass; form for the class is evaluated.
 Use &mop; generic functions &class-finalized-p; to check whether the
 class has been finalized and thus its instances can be created,
 and &finalize-inheritance; to force class finalization.</para>

<simpara>See also <xref linkend="mop-cl-defclass"/>.</simpara>
</section>

<section id="redef-class"><title>Redefining Classes
  <ulink role="clhs" url="sec_4-3-6"/></title>

<para>Trivial changes, e.g., those that can occur when doubly loading
 the same code, do not require updating the instances.
 These are the changes that do not modify the set of local slots
 accessible in instances, e.g., changes to slot options &initform-k;,
 &documentation-k;, and changes to class options
 <constant>:DEFAULT-INITARGS</constant>, &documentation-k;.</para>

<para>The instances are updated when they are first accessed, &not-e; at
 the time when the class is redefined or &make-instances-obsolete; is
 called.  When the class has been redefined several times since the
 instance was last accessed, &update-instance-for-redefined-class; is
 still called just once.</para>

</section>

</chapter>

<chapter id="data"><title>Data and Control Flow
  <ulink role="clhs" url="chap-5"/></title>

<section id="gen-ref"><title>Generalized Reference
  <ulink role="clhs" url="sec_5-1"/></title>

<para>&key-amp; markers in &defsetf; &lalist;s are supported, but the
 corresponding keywords must appear literally in the program text.</para>

<para>An attempt to modify read-only data &sig-err;.
 Program text and quoted constants loaded from files are considered
 read-only data.  This check is only performed for strings, not for
 conses, other kinds of arrays, and user-defined data types.</para>

<para>See also <xref linkend="letf"/>.</para>

</section>

<section id="setf-expansion"><title>Setf Expansions
  <ulink role="clhs" url="sec_5-1-1-2"/></title>
<para><code>(&get-setf-expansion; &form-r; &optional-amp; &env-r;)</code>,
 <code>(EXT:GET-SETF-METHOD &form-r; &optional-amp; &env-r;)</code>, and
 <code>(EXT:GET-SETF-METHOD-MULTIPLE-VALUE &form-r; &optional-amp;
  &env-r;)</code> receive as optional argument &env-r; the environment
  necessary for macro expansions. In &define-setf-expander;
  and <function>EXT:DEFINE-SETF-METHOD</function> &lalist;s, one can
  specify &environment-amp; and a variable, which will be bound to the
  environment.  This environment should be passed to all calls of
  &get-setf-expansion;, <function>EXT:GET-SETF-METHOD</function> and
 <function>EXT:GET-SETF-METHOD-MULTIPLE-VALUE</function>.  If this is
 done, even local macros will be interpreted as places correctly.</para>
</section>

<section id="extra-places"><title>Kinds of Places
  <ulink role="clhs" url="sec_5-1-2"/></title>

<para>Additional &place;s:
<variablelist>
 <varlistentry><term>&funcall;</term>
  <listitem><simpara><code>(&setf; (&funcall; #'&symbol-r; ...)
     &object-r;)</code> and
    <code>(&setf; (&funcall; '&symbol-r; ...) &object-r;)</code>
    are equivalent to <code>(&setf; (&symbol-r; ...) &object-r;)</code>.
 </simpara></listitem></varlistentry>

 <varlistentry><term>&progn;</term>
  <listitem><simpara><code>(&setf; (&progn; &form-r; ... &place-r;)
     &object-r;)</code></simpara></listitem></varlistentry>

 <varlistentry><term>&locally;</term>
  <listitem><simpara><code>(&setf; (&locally; &declaration-r; ...
     &form-r; ... &place-r;) &object-r;)</code>
  </simpara></listitem></varlistentry>

 <varlistentry><term>&if;</term>
  <listitem><simpara><code>(&setf; (&if; &cond-r;
     <replaceable>place&sub-1;</replaceable>
     <replaceable>place&sub-2;</replaceable>)
     &object-r;)</code></simpara></listitem></varlistentry>

 <varlistentry><term>&get-dispatch-macro-character;</term>
  <listitem><simpara><code>(&setf; (&get-dispatch-macro-character; ...)
     ...)</code> calls &set-dispatch-macro-character;.
 </simpara></listitem></varlistentry>

 <varlistentry><term>&lfd;:</term>
  <listitem><simpara><code>(&setf; (&lfd;) &digits-r;)</code> sets the
    default mantissa length of &long-float-t;s to &digits-r; bits.
 </simpara></listitem></varlistentry>

 <varlistentry><term>&values-list;</term>
  <listitem><simpara><code>(&setf; (&values-list; &list-r;) &form-r;)</code>
    is equivalent to <code>(&values-list; (&setf; &list-r;
     (&multiple-value-list; &form-r;)))</code>.</simpara>
   <note><simpara>Note that this &place; is restricted: it can only be
     used in &setf;, &letf;, &letf-star;, not in other positions.
 </simpara></note></listitem></varlistentry>
</variablelist></para>

</section>

<section id="misc-data"><title>Miscellaneous</title>

<simplesect id="fle"><title>Function &function-lambda-expression;</title>
<para>The &name-r; of a &foreign-function-t; is a <emphasis>string</emphasis>
(the name of the underlying &c-lang; function), not a lisp &funname;.
</para></simplesect>

<simplesect id="des-bind"><title>Macro &destructuring-bind;</title>
<para>This macro does not perform full error checking.</para></simplesect>

<simplesect id="macro-special"><title>Macros &prog1;, &prog2;, &and-m;,
 &or-m;, &psetq;, &when;, &unless;, &cond;, &case;, &multiple-value-list;,
  &multiple-value-bind;, &multiple-value-setq;</title>
<para>These macros are implemented as special operators
 (as permitted by <ulink role="clhs" url="sec_3-1-2-1-2-2"/>)
 and, as such, are rather efficient.</para></simplesect>
</section>

<section id="defconstant"><title>Macro &defconstant;</title>
<para>The initial value is &not-e; evaluated at compile time,
 just like with &defvar; and &defparameter;.
 Use &eval-when; if you need the value at compile time.</para>
<para>&constant;s may not be bound dynamically or lexically.</para>
<para>See also <xref linkend="constant-notinline"/>.</para>
<para>If you need to undo the effects of a &defconstant; form,
 &proclaim; the symbol &special-dec; (to turn the &constant; into a &dyn-var;),
 and then &proclaim; it &notspec; (to turn the &dyn-var; into a &lex-var;).
</para><note><para>If you follow the usual variable naming convention
 (<varname>*FOO*</varname> for &defvar; and &defparameter;,
 <constant>+BAR+</constant> for &defconstant;, <varname>ZOT</varname>
 for &let;/&let-star;), you will save yourself a lot of trouble.
 See also <xref linkend="faq-scope"/>.</para></note>
<section id="defconstant-similar">
 <title>Variable &suppress-similar-const-redef;</title>
<para>If the variable being defined by &defconstant; is already bound to
 a value which is not &eql; to the new value, a &warning-t; is issued.
 If, however, the new value is <firstterm>visually similar
  <indexterm id="visually-similar" significance="preferred">
   <primary>visually similar</primary></indexterm></firstterm>
 (prints to the same string, as is commonly the case when re-loading files)
 to the old one, the warning can be suppressed by setting
 &suppress-similar-const-redef; to a non-&nil; value.</para>
<para>The initial value of &suppress-similar-const-redef; is &nil;.
</para></section>
</section>

<section id="fcase"><title>Macro &fcase;</title>

<para>This macro allows specifying the test for &case;, e.g.,
<programlisting language="lisp">
(fcase string= (subseq foo 0 (position #\Space foo))
  ("first" 1)
  (("second" "two") 2)
  (("true" "yes") t)
  (otherwise nil))
</programlisting>
is the same as
<programlisting language="lisp">
(let ((var (subseq foo 0 (position #\Space foo))))
  (cond ((string= var "first") 1)
        ((or (string= var "second") (string= var "two")) 2)
        ((or (string= var "true") (string= var "yes")) t)
        (t nil)))
</programlisting>
If you use a built-in &hash-table-t; test (see <xref linkend="ht-test"/>)
as the test (e.g., &equal; instead of &string-eq; above, but not a test
defined using &defhash;), the compiler will be able to optimize the
&fcase; form better than the corresponding &cond; form.</para>
</section>

<section id="xor"><title>Function <function>EXT:XOR</function></title>
<para>This function checks that exactly one of its arguments is non-&nil;
 and, if this is the case, returns its value and index in the argument
 list as &mul-val;, otherwise returns &nil;.</para></section>

<section id="eq"><title>Function &eq;</title>

<para>&eq; compares &character-t;s and &fixnum-t;s as &eql; does.
 No unnecessary copies are made of &character-t;s and &number-t;s.
 Nevertheless, one should use &eql; as it is more portable across &cl;
 implementations.</para>

<para><code>(&let; ((&x-r; &y-r;)) (&eq; &x-r; &x-r;))</code> always
 returns &t; for any Lisp object &y-r;.
 See also <xref linkend="dffi-eq"/>.</para>

</section>

<section id="func"><title>Special Operator &function;</title>

<para><code>(&function; &symbol-r;)</code> returns the local function
 definition established by &flet; or &labels;, if it exists, otherwise
 the global function definition.</para>

<para><code>(&special-operator-p; &symbol-r;)</code> returns &nil; or
 &t;.  If it returns &t;, then <code>(&symbol-function;
  &symbol-r;)</code> returns the (useless) special operator handler.</para>

</section>

</chapter>


<chapter id="iteration"><title>Iteration
  <ulink role="clhs" url="chap-6"/></title>

<section id="loop"><title>The LOOP Facility
  <ulink role="clhs" url="sec_6-1"/></title>

<section id="loop-termination"><title>Mixing Termination Test Clauses
  <ulink role="clhs" url="sec_6-1-4"/></title>
<para>Mixing termination test clauses with different default return
 values is not allowed because it is not specifed whether
 <programlisting language="lisp">
(loop repeat 1 thereis nil never nil)
</programlisting> should return &t; (the default return value
 from <literal>NEVER</literal>) of &nil; (the default return value from
 <literal>THEREIS</literal>).</para>
</section>

<section id="loop-inter-var-finally">
 <title>Iteration variables in the loop epilogue</title>

<para>The standard is unambiguous in that the iteration variables do
 still exist in the
 <ulink role="clhs" url="sec_6-1-7-2"><literal>FINALLY</literal></ulink>
 clause, but &not-e; as to what values these variables might have.
 Therefore the code which relies on the values of such variables, e.g.,
 <programlisting language="lisp">(loop for x on y finally (return x))</programlisting>
 is inherently non-portable across &cl; implementations,
 and should be avoided.</para></section>

<section id="loop-ansi"><title>Backward Compatibility</title>
<para>There have been some tightening in the &loop; syntax between
 &cltl2; and &ansi-cl;, e.g., the following form is legal in the
 former but not the latter:<programlisting language="lisp">
(loop initially for i from 1 to 5 do (print i) finally return i)
</programlisting>
When <firstterm>&loop-ansi;</firstterm> is &nil;, such forms are still
accepted in &clisp; but elicit a warning at macro-expansion time.
When &loop-ansi; is non-&nil;, an &err-sig;.</para></section>
</section>

<section id="iter-misc"><title>Miscellaneous</title>

<para>The macros &dolist; and &dotimes; establish a single binding for
the iteration variable and assign it on each iteration.</para></section>
</chapter>

<chapter id="objects"><title>Objects <ulink role="clhs" url="chap-7"/></title>

<section id="std-meth-combo"><title>Standard Method Combination
  <ulink role="clhs" url="sec_7-6-6-2"/></title>

<para>Generic function
 <firstterm>&no-prim;<indexterm id="no-prim" significance="preferred">
   <primary>NO-PRIMARY-METHOD</primary></indexterm></firstterm>
 (similar to &no-applicable-method;) is called when there is an
 applicable method but no applicable <emphasis>primary</emphasis>
 method.</para>

<para>The default methods for &no-prim;, &no-applicable-method; and
 &no-next-method; &signal; an &error-t; of type
 <firstterm>&meth-call-err;
  <indexterm id="meth-call-err" significance="preferred">
   <primary>METHOD-CALL-ERROR</primary></indexterm></firstterm>.
 You can find out more information about the error using functions
 <function>CLOS:METHOD-CALL-ERROR-GENERIC-FUNCTION</function>,
 <function>CLOS:METHOD-CALL-ERROR-ARGUMENT-LIST</function>, and
 (only for &no-next-method;)
 <function>CLOS:METHOD-CALL-ERROR-METHOD</function>.
 Moreover, when the generic function has only one <emphasis>dispatching
 argument</emphasis>, (i.e., such an argument that not all the
 corresponding parameter specializers are &t-t;), an &error-t; of type
 <firstterm>&meth-call-type-err;
  <indexterm id="meth-call-type-err" significance="preferred">
   <primary>METHOD-CALL-TYPE-ERROR</primary></indexterm></firstterm>
  is &signal;ed, additionally making &type-error-datum; and
  &type-error-expected-type; available.</para>

</section>

</chapter>

<chapter id="structures"><title>Structures
  <ulink role="clhs" url="chap-8"/></title>

<section id="defstruct-options"><title>The options for &defstruct;</title>

<section id="defstruct-print-function">
 <title>The &print-function-k; option</title>

<para>The &print-function-k; option should contain a &lambda-expr;
 <code>(&lambda-m; (object stream depth) (declare (ignore depth)) ...)</code>
 This &lambda-expr; names a &function-t; whose task is to output the
 external representation of the &structure-object-t; &object-r; onto the
 &stream-t; &stream-r;. This may be done by outputting text onto the
 stream using &write-char;, &write-string;, &write;, &prin1;, &princ;,
 &print;, &pprint;, &format; and the like.
 The following rules must be obeyed:</para>

<itemizedlist>
 <listitem><simpara>The value of &print-escape-var; must be
  respected.</simpara></listitem>
 <listitem><simpara>The treatment of &print-pretty-var; is up to you.
 </simpara></listitem>
 <listitem><simpara>The value of &print-circle-var; need not be
  respected.  This is managed by the system.  (But the print-circle
  mechanism handles only those objects that are direct or indirect
  components of the structure.)</simpara></listitem>
 <listitem><simpara>The value of &print-level-var; is respected by
  &write;, &prin1;, &princ;, &print;, &pprint;, &format; instructions
  &format-a;, &format-s;, &format-w;, and &format; instructions
  &format-r;, &format-d;, &format-b;, &format-o;, &format-x;, &format-f;,
  &format-e;, &format-g;, &format-dollar; with not-numerical arguments.
  Therefore the print-level mechanism works automatically if only these
  functions are used for outputting objects and if they are not called
  on objects with nesting level &gt; 1. (The print-level mechanism does
  not recognize how many parentheses you have output. It only counts how
  many times it was called recursively.)</simpara></listitem>
 <listitem><simpara>The value of &print-length-var; must be respected,
  especially if you are outputting an arbitrary number of components.
 </simpara></listitem>
 <listitem><simpara>The value of &print-readably-var; must be
  respected. Remember that the values of &print-escape-var;,
  &print-level-var;, &print-length-var; are ignored if
  &print-readably-var; is true.  The value of &print-readably-var; is
  respected by &print-unreadable-object;, &write;, &prin1;, &princ;,
  &print;, &pprint;, &format; instructions &format-a;, &format-s;,
  &format-w;, and &format; instructions &format-r;, &format-d;,
  &format-b;, &format-o;, &format-x;, &format-f;, &format-e;,
  &format-g;, &format-dollar; with not-numerical arguments.  Therefore
  &print-readably-var; will be respected automatically if only these
  functions are used for printing objects.</simpara></listitem>
 <listitem><simpara>You need not worry about the values of
  &print-base-var;, &print-radix-var;, &print-case-var;,
  &print-gensym-var;, &print-array-var;, &pr-closure;,
  &pr-rpars;, &pr-indent;.</simpara></listitem>
</itemizedlist>
</section>

<section id="defstruct-inherit"><title>The &inherit-k; option</title>
<para>The &inherit-k; option is exactly like &include-k; except that it
 does not create new accessors for the inherited slots (this is a
 &clisp; extension).</para></section>

</section>

<section id="defstruct-mop"><title>The structure &mop;</title>
<para>The following functions accept a structure &name-r; as the only argument.
 If &defstruct; was given the &type-k; option (i.e., &defstruct; did
 &not-e; define a new type), then <code>(&find-class; &name-r;)</code>
 fails (and the regular &clos; &mop; is not applicable), but these
 functions still work.</para>
<variablelist>
<varlistentry><term><function>EXT:STRUCTURE-SLOTS</function></term>
 <listitem><simpara>Return the &list-t; of &esdmo;s.
</simpara></listitem></varlistentry>
<varlistentry><term><function>EXT:STRUCTURE-DIRECT-SLOTS</function></term>
 <listitem><simpara>Return the &list-t; of &dsdmo;s.
</simpara></listitem></varlistentry>
<varlistentry><term><function>EXT:STRUCTURE-KEYWORD-CONSTRUCTOR</function></term>
 <listitem><simpara>Return the name (a &symbol-t;) of the keyword
   constructor function for the structure, or &nil; if the structure has
   no keyword constructor.</simpara></listitem></varlistentry>
<varlistentry><term><function>EXT:STRUCTURE-BOA-CONSTRUCTORS</function></term>
 <listitem><simpara>Return the &list-t; of names (&symbol-t;s)
  of BOA constructors for the structure.</simpara></listitem></varlistentry>
<varlistentry><term><function>EXT:STRUCTURE-COPIER</function></term>
 <listitem><simpara>Return the name (a &symbol-t;) of the copier for the
   structure.</simpara></listitem></varlistentry>
<varlistentry><term><function>EXT:STRUCTURE-PREDICATE</function></term>
 <listitem><simpara>Return the name (a &symbol-t;) of the predicate for
   the structure.</simpara></listitem></varlistentry>
</variablelist>
</section>

</chapter>


<chapter id="conditions"><title>Conditions
  <ulink role="clhs" url="chap-9"/></title>

<para>When an error occurred, you are in a break loop. You can evaluate
 forms as usual. The &help; command (or help key if there is one) lists
 the available &debugger; commands.</para>

<section id="cond-nl"><title>Embedded Newlines in Condition Reports
  <ulink role="clhs" url="sec_9-1-3-1-3"/></title>
<para>The error message prefix for the first line is <quote>*** - </quote>.
 All subsequent lines are indented by 6 characters.
 Long lines are broken on &whitespace;
 (see <xref linkend="fill-stream"/>).</para>
</section>

<section id="cond-fname"><title>Mentioning Containing Function in
  Condition Reports <ulink role="clhs" url="sec_9-1-3-1-5"/></title>
<para>Contrary to the recommendation of the standard, &clisp; usually
 does print the name of the containing function to simplify debugging
 in batch mode, see &exit-on-error;.</para>
</section>

<section id="restarts"><title>Interfaces to Restarts
  <ulink role="clhs" url="sec_9-1-4-2-2"/></title>

<formalpara id="restart-case"><title>Macro &restart-case;</title>
 <para>In <code>(&restart-case; &form-r; {&restart-clause-r;}*)</code>,
  the argument list can also be specified after the keyword/value pairs
  instead of before them, i.e., each &restart-clause-r; can be either
  <code>(<varname>restart-name</varname> &args;
   {<replaceable>keyword-value-pair</replaceable>}* {&form-r;}*)</code>
  or <code>(<replaceable>restart-name</replaceable>
   {<replaceable>keyword-value-pair</replaceable>}* &args; {&form-r;}*)</code>.
</para></formalpara>

<formalpara id="with-restarts"><title>Macro &with-restarts;</title>
<para>The macro &with-restarts; is like &restart-case;, except that the
 forms are specified after the restart clauses instead of before them,
 and the restarts created are not implicitly associated with any &condition-t;.
 <code>(&with-restarts; ({&restart-clause-r;}*) {&form-r;}*)</code> is
 therefore equivalent to <code>(&restart-case; (&progn; {&form-r;}*)
 {&restart-clause-r;}*)</code>.</para></formalpara>

<formalpara id="compute-restarts"><title>Function &compute-restarts;</title>
<para>&compute-restarts; and &find-restart; behave as specified in
 &ansi-cl;: If the optional &cond-r; argument is non-&nil;,
 only &restart-t;s associated with that &condition-t;
 and &restart-t;s associated with no &condition-t; at all are considered.
 Therefore the effect of associating a restart to a condition is not to
 activate it, but to hide it from other conditions.
 This makes the syntax-dependent implicit association performed by
 &restart-case; nearly obsolete.</para></formalpara>

<formalpara id="muffle-cerrors"><title>Macro &muffle-cerrors;</title>
<para>The macro <code>(&muffle-cerrors; {&form-r;}*)</code>
 executes the &form-r;s; when a &cont-err; occurs whose &continue; &restart-t;
 can be invoked non-interactively (this includes all &cont-err;s signaled
 by the function &cerror;), no message is printed, instead, the &continue;
 &restart-t; is invoked.</para></formalpara>

<formalpara id="appease-cerrors"><title>Macro &appease-cerrors;</title>
<para>The macro <code>(&appease-cerrors; {&form-r;}*)</code>
 executes the &form-r;s; when a &cont-err; occurs whose &continue; &restart-t;
 can be invoked non-interactively (this includes all &cont-err;s &signal;ed
 by the function &cerror;), it is reported as a &warning-t;, and the
 &continue; &restart-t; is invoked.</para></formalpara>

<formalpara id="abort-on-error"><title>Macro &abort-on-error;</title>
<para>The macro <code>(&abort-on-error; {&form-r;}*)</code>
 executes the &form-r;s; when an &error-t; occurs, or when a &ctrl-c;
 interrupt occurs, the error message is printed and the &abort-s;
 &restart-t; is invoked.</para></formalpara>

<formalpara id="exit-on-error"><title>Macro &exit-on-error;</title>
<para>The macro <code>(&exit-on-error; {&form-r;}*)</code>
 executes the &form-r;s; when an &error-t; occurs, or when a &ctrl-c;
 interrupt occurs, the error message is printed and &clisp; terminates
 with an error status.</para></formalpara>

<formalpara id="err-pr-bt"><title>Variable &err-pr-bt;</title>
<para>When this variable is non-&nil; the error message printed by
 &abort-on-error; and &exit-on-error; includes the &backtrace; (stack).
</para></formalpara>

<formalpara id="global-handler"><title>Function &set-global-handler;</title>
<para>The function <code>(&set-global-handler; &cond-r; handler)</code>
 establishes a global handler for the &cond-r;.
 The <replaceable>handler</replaceable> should be &funcall;able (a
 &symbol-t; or a &function-t;).
 If it returns, the next applicable handler is invoked, so if you do
 &not-e; want to land in the &debugger;, it should &not-e; return.
 E.g., the option &opt-on-error; <option>abort</option> and the macro
 &abort-on-error; are implemented by installing the following handler:
 <programlisting language="lisp">(defun sys::abortonerror (condition)
  (sys::report-error condition)
  (&invoke-restart; (&find-restart; '&abort; condition)))</programlisting>
 When <replaceable>handler</replaceable> is &nil;, the handler
 for &cond-r; is removed and returned.
 When &cond-r; is also &nil;, all global handlers are removed and returned
 as a &list-t;, which can then be passed to &set-global-handler; as the
 first argument and the handlers re-established.</para></formalpara>

<formalpara id="without-global-handlers">
 <title>Macro &without-global-handlers;</title>
<para>The macro <code>(&without-global-handlers; &body-amp;
  &body-r;)</code> removes all global handlers by <code>(&set-global-handler;
 &nil; &nil;)</code>, executes &body-r; (where unhandled conditions now
 invoke the &debugger;), and then restores the handlers.</para></formalpara>

</section>

<section id="assertions"><title>Assertions
  <ulink role="clhs" url="sec-9-1-5"/></title>

<para>The prompt for replacement values (&restart-t;s &store-value-s;,
&use-value-s; et al) is terminated with &prompt-finish; to indicate that
the value entered is treated as usual for the Lisp &repl;, i.e., it is
&eval;uated.</para>

</section>

</chapter>


<chapter id="symbols"><title>Symbols <ulink role="clhs" url="chap-10"/></title>
<para>No notes.</para>
</chapter>

<chapter id="packages"><title>Packages
  <ulink role="clhs" url="chap-11"/></title>

<variablelist><title>The &ansi-cl; packages present in &clisp;</title>
 <varlistentry><term>&cl-pac;</term>
  <listitem><simpara>with the nicknames <quote role="package">CL</quote>
    and <quote role="package">LISP</quote></simpara></listitem></varlistentry>
 <varlistentry><term>&clu-pac;</term>
  <listitem><simpara>with the nicknames <quote role="package">CL-USER</quote>
    and <quote role="package">USER</quote></simpara></listitem></varlistentry>
 <varlistentry><term>&kwd-pac;</term>
  <listitem><simpara>with no nicknames
 </simpara></listitem></varlistentry>
</variablelist>

<section id="pack-intro"><title>Introduction to Packages
  <ulink role="clhs" url="sec_11-1-1"/></title>

<section id="make-pack"><title>Function &make-package;</title>
<para>The default value of the &use-k; argument is
 <literal role="data">(&cl-pac;)</literal>.</para>

<para>&make-package; accepts additional keyword arguments
 &case-sensitive-k; and &case-inverted-k; (but &not-e; &modern-k;!)
</para></section>

<section id="defpack"><title>Macro &defpackage;</title>
<para>&defpackage; accepts additional options &case-sensitive-k;,
 &case-inverted-k;, and &modern-k;.</para>
<para>When the package being defined already exists, it is modified as
 follows (and in this order):<variablelist>
  <varlistentry><term>&case-sensitive-k;</term>
   <listitem><simpara>adjusted with <code>(&setf; &pack-sensitive;)</code>
     (with a warning)</simpara></listitem></varlistentry>
  <varlistentry><term>&case-inverted-k;</term>
   <listitem><simpara>adjusted with <code>(&setf; &pack-inverted;)</code>
     (with a warning)</simpara></listitem></varlistentry>
  <varlistentry><term>&modern-k;</term>
   <listitem><para>if &cl-pac; is being used, it is un-used and
     &cs-cl; is used instead; also, &cs-cl; is used instead of &cl-pac;
     throughout the &defpackage; form, e.g.,<programlisting language="lisp">
(&defpackage; "FOO"
  (&modern-k; &t;)
  (&use-k; "COMMON-LISP" "EXT"))
</programlisting>is equivalent to<programlisting language="lisp">
(&defpackage; "FOO"
  (&case-sensitive-k; &t;)
  (&case-inverted-k; &t;)
  (&use-k; "CS-COMMON-LISP" "EXT"))
</programlisting></para>
    <simpara><code>(&modern-k; &nil;)</code> reverts the
      effects of <code>(&modern-k; &t;)</code>.</simpara>
  </listitem></varlistentry>
  <varlistentry><term><constant>:NICKNAMES</constant></term>
   <listitem><simpara>adjusted with &rename-package;
  </simpara></listitem></varlistentry>
  <varlistentry><term>&documentation-k;</term>
   <listitem><simpara>reset to the new value with <code>(&setf;
      &documentation;)</code></simpara></listitem></varlistentry>
  <varlistentry><term><constant>:SHADOW</constant></term>
   <listitem><simpara>adjusted with &shadow;
  </simpara></listitem></varlistentry>
  <varlistentry><term><constant>:SHADOWING-IMPORT-FROM</constant></term>
   <listitem><simpara>adjusted with &shadowing-import;
  </simpara></listitem></varlistentry>
  <varlistentry><term>&use-k;</term>
   <listitem><simpara>adjusted with &use-package; and &unuse-package;
  </simpara></listitem></varlistentry>
  <varlistentry><term><constant>:IMPORT-FROM</constant></term>
   <listitem><simpara>adjusted with &import;
  </simpara></listitem></varlistentry>
  <varlistentry><term><constant>:INTERN</constant></term>
   <listitem><simpara>adjusted with &intern; (but &not-e; &unintern;)
  </simpara></listitem></varlistentry>
  <varlistentry><term><constant>:EXPORT</constant></term>
   <listitem><simpara>adjusted with &intern; and &export; (but &not-e;
     &unexport;)</simpara></listitem></varlistentry>
  <varlistentry><term><constant>:SIZE</constant></term>
   <listitem><simpara>ignored</simpara></listitem></varlistentry>
</variablelist></para></section>

<section id="re-export"><title>Function &re-export;</title>

<para>The function <code>(&re-export; <replaceable>FROM-PACK</replaceable>
  <replaceable>TO-PACK</replaceable>)</code> re-&export;s all external
 &symbol-t;s from <replaceable>FROM-PACK</replaceable> also from
 <replaceable>TO-PACK</replaceable>, provided it already uses
 <replaceable>FROM-PACK</replaceable>; and &signal;s an &error-t; otherwise.
</para></section>

<section id="pack-inverted"><title>Function &pack-inverted;</title>
 <para>Returns &t; if the argument is a
  <link linkend="pack-case-inverted">case-inverted package</link>.
  This function is &setf;able, although it is probably not a good idea
  to change the case-inverted status of an existing package.</para></section>

<section id="pack-sensitive"><title>Function &pack-sensitive;</title>
 <para>Returns &t; if the argument is a &case-sensitive-k; &package-t;.
  This function is &setf;able, although it is probably not a good idea
  to change the case-sensitive status of an existing package.</para></section>

</section>

<section id="pack-lock"><title>Constraints on the &cl-pac; Package
  for Conforming Programs - package locking
 <ulink role="clhs" url="sec_11-1-2-1-2"/></title>

<note><para>Locking discussed in this section has nothing to do with
  &mutex-lock;.</para></note>

<formalpara><title>Function <firstterm>&package-lock;
   <indexterm id="pack-lock-f" significance="preferred">
    <primary>PACKAGE-LOCK</primary></indexterm></firstterm></title>
<para>Packages can be <quote>locked</quote>.
When a package is locked, attempts to change its symbol table or
redefine functions which its symbols name result in a &cont-err;
(continuing overrides locking for this operation).
When &suppress-check-redef; is &t; (&not-e; a good idea!), the &error-t;
is not &signal;ed for redefine operations.
Function <code>(&package-lock; &pack-r;)</code>
returns the generalized boolean indicating whether the &pack-r; is locked.
A package (or a list thereof) can be locked using <code>(&setf;
 (&package-lock; <replaceable>package-or-list</replaceable>) &t;)</code>.
&clisp; locks its system packages (specified in the variable
&sys-pack-list;).</para></formalpara>

<formalpara><title>Macro &without-package-lock;</title>
<para>If you want to evaluate some forms with certain packages unlocked,
 you can use
 <firstterm>&without-package-lock;
  <indexterm id="without-pack-lock" significance="preferred">
   <primary>WITHOUT-PACKAGE-LOCK</primary></indexterm></firstterm>:
<programlisting language="lisp">
(&without-package-lock; (&cl-pac; &ext-pac; &clos-pac;)
  (defun restart () ...))
</programlisting>
or
<programlisting language="lisp">
(&without-package-lock; (&cl-pac;) (trace read-line))
</programlisting>
<code>(&without-package-lock; () ...)</code>
temporarily unlocks all packages in &sys-pack-list;.</para></formalpara>

<formalpara><title>Variable &sys-pack-list;</title>
<para>This variable specifies the default packages to be locked by &savemem;
 and unlocked by &without-package-lock; as a list of package names.
 You may add names to this list, e.g., a module will add its package,
 but you should &not-e; remove &clisp; internal packages from this list.
</para></formalpara>

<formalpara><title>Discussion - see also
  <ulink url="http://groups.google.com/group/comp.lang.lisp/msg/d87844da9f4d35aa">the USENET posting</ulink> by
  <author><firstname>Steven M.</firstname> <surname>Haflich</surname>
   <email>haflich@pacbell.net</email></author></title>
<para>This should prevent you from accidentally hosing yourself with
<programlisting language="lisp">
(&defstruct; instance ...)
</programlisting>
and allow enforcing modularity.
Note that you will also get the &cont-err; when you try to
assign (with &setq;, &psetq;, etc.) a value to an internal special
variable living in a locked package and not accessible in your current
&package-var;, but only in the interpreted code and during compilation.
There is no check for package locks in compiled code because of the
performance considerations.
</para></formalpara>

</section>

<section id="clupack"><title>The
  <quote role="package">COMMON-LISP-USER</quote> Package
  <ulink role="clhs" url="sec_11-1-2-2"/></title>

<para>The &clu-pac; package uses the &cl-pac; and &ext-pac; packages.</para>

</section>

<section id="imppack"><title>Implementation-Defined Packages
  <ulink role="clhs" url="sec_11-1-2-4"/></title>

<para>The following additional packages exist:</para>
<variablelist><title>Implementation-Defined Packages</title>
 <varlistentry><term>&clos-pac;</term><listitem>
   <simpara>&export;s all &clos;-specific symbols, including some
    <link linkend="clos-diff">additional symbols</link>.
 </simpara></listitem></varlistentry>
 <varlistentry id="sys-pac"><term>&sys-pac;</term><listitem>
   <simpara>has the nickname <quote role="package">SYS</quote>,
    and has no &export;ed symbols.  It defines many system internals.
 </simpara></listitem></varlistentry>
 <varlistentry id="ext-pac"><term>&ext-pac;</term><listitem><simpara>
    is the umbrella package for all extensions: it imports and &re-export;s
    all the external symbols in all &clisp; extensions, so a simple
    <code>(&use-package; "EXT")</code> is enough to
    make all the extensions available in the current package.
    This package uses packages (in addition to &cl-pac;):
    &posix-pac;, &socket-pac;, &gstream-pac;, &gray-pac;,
    &i18n-pac;, &custom-pac;.</simpara></listitem></varlistentry>
 <varlistentry><term>&charset-pac;</term><listitem>
   <simpara>defines and &export;s some character sets, for use with
    &make-encoding; and as &extfmt; argument.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&ffi-pac;</term><listitem>
   <simpara>implements the <link linkend="dffi">foreign function
     interface</link>.  Some platforms only.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&screen-pac;</term><listitem>
   <simpara>defines an API for <link linkend="screen">random screen
     access</link>.  Some platforms only.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&cs-cl;</term><term>&cs-clu;</term><listitem>
   <simpara>&case-sensitive-k; versions of &cl-pac; and &clu-pac;.
    See <xref linkend="package-case"/>.</simpara></listitem></varlistentry>
</variablelist>

<para>All pre-existing packages except &clu-pac; belong to the
 implementation, in the sense that the programs that do not follow
 <ulink role="clhs" url="sec_11-1-2-1-2"/>
 (<quote>Constraints on the &cl-pac; Package for Conforming Programs</quote>)
 cause undefined behavior.</para>

</section>

<section id="package-case"><title>Package Case-Sensitivity</title>

<para>&clisp; supports programs written with case sensitive symbols. For
example, with case sensitive symbols, the symbols <literal>cdr</literal>
(the function equivalent to &rest;) and the symbol <literal>CDR</literal>
(a user-defined type denoting a Call Data Record) are different and unrelated.
</para>

<para>There are some incompatibilities between programs assuming case
sensitive symbols and programs assuming the &ansi-cl; case insensitive symbols.
For example, <code>(eq 'KB 'Kb)</code> evaluates to false in a case
sensitive world and to true in a case insensitive world. However, unlike some
commercial &cl; implementations, &clisp; allows both kinds of programs to
coexist in the same process and interoperate with each other. Example:
<variablelist>
 <varlistentry><term><filename>OLD.lisp</filename></term>
  <listitem><programlisting language="lisp">
(&in-package; "OLD")
(&defun; FOO () ...)
</programlisting></listitem></varlistentry>
 <varlistentry><term><filename>modern.lisp</filename></term>
  <listitem><programlisting language="lisp">
(in-package "NEW")
(defun bar () (old:foo))
(symbol-name 'bar) ; <computeroutput>"bar"</computeroutput>
</programlisting></listitem></varlistentry></variablelist></para>

<para>This is achieved through specification of the symbol case policy at
the package level. A <firstterm>modern package
  <indexterm id="pack-modern" significance="preferred">
   <primary>&package-t;</primary><secondary>modern</secondary>
 </indexterm></firstterm>
 is one that is declared to be both case-sensitive and case-inverted and
 which use the symbols from the &cs-cl; package.</para>

<para>A <firstterm>case-sensitive package
  <indexterm id="pack-case-sensitive" significance="preferred">
   <primary>&package-t;</primary>
   <secondary>case-sensitive</secondary></indexterm></firstterm>
 is one whose &defpackage; declaration (or &make-package;
 creation form) has the option <code>(&case-sensitive-k; &t;)</code>.
 In a case-sensitive package, the reader does &not-e; uppercase the
 symbol name before calling &intern;.  Similarly, the printer, when
 printing the &symbol-name; part of a &symbol-t; (i.e. the part after
 the package markers), behaves as if the readtable's case were set
 to <constant>:PRESERVE</constant>.
 See also <xref linkend="pack-sensitive"/>.</para>

<para>A <firstterm>case-inverted package
  <indexterm id="pack-case-inverted" significance="preferred">
   <primary>&package-t;</primary>
   <secondary>case-inverted</secondary></indexterm>
 </firstterm> is one whose &defpackage; declaration (or &make-package;
 creation form) has the option <code>(&case-inverted-k; &t;)</code>.
 In the context of a case-inverted package, symbol names are
 case-inverted: upper case characters are mapped to lower case, lower
 case characters are mapped to upper case, and other characters are left
 untouched.  Every symbol thus conceptually has two symbol names: an
 old-world symbol name and a modern-world symbol name, which is the
 case-inverted old-world name.  The first symbol name is returned by the
 function &symbol-name;, the modern one by the
 function <function>cs-cl:symbol-name</function>.  The internal
 functions for creating or looking up symbols in a package, which
 traditionally took a string argument, now conceptually take two string
 arguments: old-style-string and inverted-string.  Actually, a function
 like &intern; takes the old-style-string as argument and computes the
 inverted-string from it; whereas the
 function <function>cs-cl:intern</function> takes the inverted-string as
 argument and computes the old-style-string from it.
 See also <xref linkend="pack-inverted"/>.</para>

<para>For a few built-in functions, a variant for the case-inverted
world is defined in the &cs-cl; package, which has the nickname
 <quote role="package">CS-CL</quote>:<variablelist>
  <varlistentry><term><function>cs-cl:symbol-name</function></term>
   <listitem><simpara>returns the case-inverted symbol name.
  </simpara></listitem></varlistentry>
  <varlistentry><term><function>cs-cl:intern</function></term>
   <term><function>cs-cl:find-symbol</function></term>
   <listitem><simpara>work consistently with
     <function>cs-cl:symbol-name</function>.</simpara></listitem></varlistentry>
  <varlistentry><term><function>cs-cl:shadow</function></term>
   <term><function>cs-cl:find-all-symbols</function></term>
   <term><function>cs-cl:string=</function></term>
   <term><function>cs-cl:string/=</function></term>
   <term><function>cs-cl:string&lt;</function></term>
   <term><function>cs-cl:string&gt;</function></term>
   <term><function>cs-cl:string&lt;=</function></term>
   <term><function>cs-cl:string&gt;=</function></term>
   <term><function>cs-cl:string-trim</function></term>
   <term><function>cs-cl:string-left-trim</function></term>
   <term><function>cs-cl:string-right-trim</function></term>
   <listitem><simpara>convert a &symbol-t; to a &string-t; and therefore
     exist in a variant that uses <function>cs-cl:symbol-name</function>
     instead of &symbol-name;.</simpara></listitem></varlistentry>
  <varlistentry><term><function>cs-cl:make-package</function></term>
   <listitem><simpara>creates a case-inverted &package-t;.
</simpara></listitem></varlistentry></variablelist></para>

<section id="cs-clu"><title>User Package for the Case-sensitive World</title>
<para>A package &cs-clu; is provided for the user to modify and work in.
It plays the same role as &clu-pac;, but for the case-sensitive
world.</para></section>

<section id="cs-pack-name"><title>Package Names</title>
<para>The handling of package names is unchanged.  Package names are
 still usually uppercase.  The package names are also subject to
 <code>(&readtable-case; &readtable-var;)</code>.</para></section>

<section id="cs-gensym-kwd"><title>Gensyms and Keywords</title>
<para>Note that gensyms and keywords are still treated traditionally:
even in a case-sensitive package,<programlisting language="lisp">
(&string-eq; '#:FooBar '#:foobar)
<computeroutput>&t;</computeroutput>
(&eq; ':KeyWord ':keyword)
<computeroutput>&t;</computeroutput></programlisting>
We believe this has a limited negative impact for the moment,
but can be changed some time in the future.</para></section>

<section id="case-sensitive-migration"><title>Migration Tips</title>

<para>The following practices will pose no problems when migrating to a
modern case-sensitive world:
<itemizedlist>
<listitem><simpara>Using &ansi-cl; symbols in lowercase.</simpara></listitem>
<listitem><simpara>Macros that create symbols by suffixing or prefixing
  given symbols.</simpara></listitem>
<listitem><simpara>Comparing symbol names as in
  <code>(&string-eq; (&symbol-name; &x-r;) (&symbol-name; &y-r;))</code>.
</simpara></listitem></itemizedlist></para>

<para>The following practices will not work in a case-sensitive world or
can give problems:
<itemizedlist>
<listitem><simpara>Accessing the same symbol in both upper- and
  lowercase from the same source file.</simpara></listitem>
<listitem><simpara>Macros that create symbols in other packages than the
  original symbols.</simpara></listitem>
<listitem><simpara>Comparing &symbol-name; return values with &eq;.
</simpara></listitem>
<listitem><simpara>Comparing <code>(&symbol-name; x)</code> with
  <code>(cs-cl:symbol-name y)</code>.</simpara></listitem>
</itemizedlist></para>

</section>

<section id="case-sensitive-startup">
 <title>Using case-sensitive packages by default</title>

<para>&clisp; supports a command-line option &opt-modern; that
 sets the &package-var; initially to the &cs-clu; package, and
 &print-case-var; to <constant>:DOWNCASE</constant>.</para>

<para>For packages to be located in the <quote>modern</quote>
 (case-sensitive) world, you need to augment their &defpackage;
 declaration by adding the option <code>(&modern-k; &t;)</code>,
 see <xref linkend="defpack"/>.</para>

</section>
</section>

</chapter>

<chapter id="numbers"><title>Numbers <ulink role="clhs" url="chap-12"/></title>

<section id="num-types"><title>Numeric Types</title>

<para>The type &number-t; is the disjoint union of the types
 &real-t; and &complex-t; (<ulink url="clhs/glo">exhaustive
 partition</ulink>)</para>

<para>The type &real-t; is the disjoint union of the types
 &rational-t; and &float-t;.</para>

<para>The type &rational-t; is the disjoint union of the types
 &integer-t; and &ratio-t;.</para>

<para>The type &integer-t; is the disjoint union of the types
 &fixnum-t; and &bignum-t;.</para>

<para>The type &float-t; is the disjoint union of the types
 &short-float-t;, &single-float-t;, &double-float-t; and
 &long-float-t;.</para>

</section>

<section id="num-concepts"><title>Number Concepts
  <ulink role="clhs" url="sec_12-1"/></title>


<section id="num-ops"><title>Numeric Operations
  <ulink role="clhs" url="sec_12-1-1"/></title>

<section id="int-func-ext"><title>Additional Integer Functions</title>

<formalpara id="factorial"><title>Function <function>EXT:!</function></title>
<para><code>(<function>EXT:!</function> &n-r;)</code> returns the
 factorial of &n-r;, &n-r; being a nonnegative &integer-t;.</para></formalpara>

<formalpara id="exquo"><title>Function <function>EXT:EXQUO</function></title>
<para><code>(<function>EXT:EXQUO</function> &x-r; &y-r;)</code> returns
 the integer quotient <varname>x/y</varname> of two integers
 &x-r;,&y-r;, and &signal;s an &error-t; when the quotient is not
 integer.  (This is more efficient than &slash;.)</para></formalpara>

<formalpara id="xgcd"><title>Function <function>EXT:XGCD</function></title>
<para><code>(<function>EXT:XGCD</function> &x1-r; ... &xn-r;)</code>
 returns the values &l-r;, &k1-r;, ..., &kn-r;, where &l-r; is the
 greatest common divisor of the integers &x1-r;, ..., &xn-r;, and
 &k1-r;, ..., &kn-r; are the integer coefficients such that
<programlisting language="lisp">
&l-r; = (&gcd; &x1-r; ... &xn-r;)
  = (+ (* &k1-r; &x1-r;) ... (* &kn-r; &xn-r;))
</programlisting></para></formalpara>

<formalpara id="mod-expt"><title>Function &mod-expt;</title>
<para><code>(&mod-expt; &k-r; &l-r; &m-r;)</code>
 is equivalent to <code>(&mod; (&expt; &k-r; &l-r;) &m-r;)</code>
 except it is more efficient for very large arguments.</para></formalpara>

</section>

<section id="float-decode"><title>Function &decode-float;</title>

<para>&float-radix; always returns <returnvalue>2</returnvalue>.</para>

<para><code>(&float-digits; &number-r; &digits-r;)</code> coerces
 &number-r; (a &real-t;) to a floating point number with at least
 &digits-r; mantissa digits.  The following always evaluates to &t;:
 <programlisting language="lisp">
(&geq; (&float-digits; (&float-digits; &number-r; &digits-r;)) &digits-r;)
</programlisting></para>

</section>

<section id="bool-ops"><title>Boolean Operations
  <ulink role="clhs" url="convar_boole-_cm_boole-xor"/></title>

 <table id="bool-op-table" frame="all">
  <title>Boolean operations</title>
  <tgroup cols="2" colsep="1" rowsep="1" align="left">
   <thead><row><entry>constant</entry><entry>value</entry></row></thead><tbody>
    <row><entry>&boole-clr;</entry><entry>0</entry></row>
    <row><entry>&boole-set;</entry><entry>15</entry></row>
    <row><entry>&boole-1;</entry><entry>10</entry></row>
    <row><entry>&boole-2;</entry><entry>12</entry></row>
    <row><entry>&boole-c1;</entry><entry>5</entry></row>
    <row><entry>&boole-c2;</entry><entry>3</entry></row>
    <row><entry>&boole-and;</entry><entry>8</entry></row>
    <row><entry>&boole-ior;</entry><entry>14</entry></row>
    <row><entry>&boole-xor;</entry><entry>6</entry></row>
    <row><entry>&boole-eqv;</entry><entry>9</entry></row>
    <row><entry>&boole-nand;</entry><entry>7</entry></row>
    <row><entry>&boole-nor;</entry><entry>1</entry></row>
    <row><entry>&boole-andc1;</entry><entry>4</entry></row>
    <row><entry>&boole-andc2;</entry><entry>2</entry></row>
    <row><entry>&boole-orc1;</entry><entry>13</entry></row>
    <row><entry>&boole-orc2;</entry><entry>11</entry></row>
 </tbody></tgroup></table>

</section>

<section id="byte-type"><title>Byte Operations on Integers
  <ulink role="clhs" url="sec_12-1-1-3-2"/></title>

<para>Byte specifiers are objects of built-in type &byte-t;,
 not &integer-t;s.</para>

</section>

<section id="float-notes"><title>Floating Point Arithmetics</title>

<formalpara id="expt"><title>Function &expt;</title>
<para><code>(&expt; &base-r; <replaceable>exponent</replaceable>)</code>
 is not very precise if <replaceable>exponent</replaceable> has a large
 absolute value.</para></formalpara>

<formalpara id="log"><title>Function &log;</title>
<para><code>(&log; &number-r; &base-r;)</code> &sig-err; if
 <literal>&base-r; = 1</literal>.</para></formalpara>

<formalpara id="pi"><title>Constant &pi-v;</title>
 <para>The value of &pi-v; is a &long-float-t; with the precision given
  by &lfd-l;.  When this precision is changed, the value of &pi-v; is
  automatically recomputed.  Therefore &pi-v; is &not-e; a &constant;.
</para></formalpara>

<formalpara id="ucpt"><title>Function &upgraded-complex-part-type;</title>
<para>When the argument is not a &recog-subt; or &real-t;,
 &upgraded-complex-part-type; &signal;s an &error-t;, otherwise it
 returns its argument (even though a &complex-t; number in &clisp; can
 always have &realpart; and &imagpart; of any type) because it allows
 the most precise type inference.</para></formalpara>

<formalpara id="default-float-format">
 <title>Variable &default-float-format;</title>
<para>When rational numbers are to be converted to floats (due to
 &float;, &coerce;, &sqrt; or a transcendental function), the result
 type is given by the variable &default-float-format;.
 See also &read-default-float-format-var;.</para></formalpara>

<formalpara id="no-underflow"><title>Macro &no-underflow;</title>
<para>The macro <code>(&no-underflow; {&form-r;}*)</code> executes the
 &form-r;s, with errors of type &floating-point-underflow-t; inhibited.
 Floating point operations will silently return zero instead of
 &signal;ing an &error-t; of type &floating-point-underflow-t;.
</para></formalpara>

<formalpara id="float-invalid-op">
 <title>Condition &floating-point-invalid-operation-t;</title>
<para>This &condition-t; is never &signal;ed by &clisp;.</para></formalpara>

<formalpara id="float-inexact">
 <title>Condition &floating-point-inexact-t;</title>
<para>This &condition-t; is never &signal;ed by &clisp;.</para></formalpara>

</section>

</section>

<section id="num-const"><title>Implementation-Dependent Numeric Constants
  <ulink role="clhs" url="sec_12-1-2"/></title>

<section id="fixnum-lim"><title>Fixnum Limits</title>

<table id="fixnum-lim-table" frame="all"><title>Fixnum limits</title>
 <tgroup cols="3" colsep="1" rowsep="1" align="center">&cpu-type-header;<tbody>
   <row><entry>&most-positive-fixnum;</entry>
    <entry>2<superscript>24</superscript>-1 = 16777215</entry>
    <entry>2<superscript>48</superscript>-1 = 281474976710655</entry></row>
   <row><entry>&most-negative-fixnum;</entry>
    <entry>-2<superscript>24</superscript> = -16777216</entry>
    <entry>-2<superscript>48</superscript> = -281474976710656</entry></row>
</tbody></tgroup></table></section>

<section id="bignum-lim"><title>Bignum Limits</title>

<para>&bignum-t;s are limited in size.  Their maximum size is
 <literal>32*(2<superscript>16</superscript>-2)=2097088</literal> bits.
 The largest representable &bignum-t; is therefore
 <literal>2<superscript>2097088</superscript>-1</literal>.</para></section>

<section id="float-lim"><title>Float Limits</title>

<para>Together with &pi-v;, the other &long-float-t; constants
 <simplelist columns="2">
  <member>&least-negative-long-float;</member>
  <member>&least-negative-normalized-long-float;</member>
  <member>&least-positive-long-float;</member>
  <member>&least-positive-normalized-long-float;</member>
  <member>&long-float-epsilon;</member>
  <member>&long-float-negative-epsilon;</member>
  <member>&most-negative-long-float;</member>
  <member>&most-positive-long-float;</member></simplelist>
 are recomputed whenever &lfd-l; is &setf;ed.
 They are &not-e; &constant;s.</para>

<warning id="long-float-wider-than-bignum"><para>Since the exponent of a
  &long-float-t; is a <link linkend="floating-types-table">signed 32-bits
   integer</link>, &most-positive-long-float; is about
  <literal>2<superscript>2<superscript>31</superscript></superscript></literal>,
  which is <emphasis>much</emphasis> larger that the largest
  representable &bignum-t;, which is <link linkend="bignum-lim">less than</link>
  <literal>2<superscript>2<superscript>21</superscript></superscript></literal>.
  This, obviously, means that &round;, &truncate;, &floor; and &ceiling;
  &sig-err; on large &long-float-t;s.
  Less obviously, this means that <code>(&format; &nil; "&format-e;"
  &most-positive-long-float;)</code> also fails.</para></warning>

</section>

</section>

<section id="float-subst"><title>Rule of Float Substitutability
  <ulink role="clhs" url="sec_12-1-3-3"/></title>

<para>When a mathematical function may return an exact (&rational-t;) or
 inexact (&float-t;) result, it always returns the exact result.</para>

</section>

<section id="float-comp"><title>Floating-point Computations
  <ulink role="clhs" url="sec_12-1-4"/></title>

<para>There are four floating point types: &short-float-t;,
 &single-float-t;, &double-float-t; and &long-float-t;:
<informaltable id="floating-types-table" frame="all">
<tgroup cols="5" colsep="1" rowsep="1" align="center">
<thead><row><entry>type</entry><entry>sign</entry><entry>mantissa</entry>
       <entry>exponent</entry><entry>comment</entry></row></thead>
<tbody><row><entry>&short-float-t;</entry><entry>1 bit</entry>
 <entry>16+1 bits</entry><entry>8 bits</entry><entry>immediate</entry></row>
       <row><entry>&single-float-t;</entry><entry>1 bit</entry>
 <entry>23+1 bits</entry><entry>8 bits</entry><entry>&ieee-bfp;</entry></row>
       <row><entry>&double-float-t;</entry><entry>1 bit</entry>
 <entry>52+1 bits</entry><entry>11 bits</entry><entry>&ieee-bfp;</entry></row>
       <row><entry>&long-float-t;</entry><entry>1 bit</entry>
 <entry>&gt;=64 bits</entry><entry>32 bits</entry><entry>variable
 length</entry></row></tbody></tgroup></informaltable></para>

<para>The single and double float formats are those of the &ieee-bfp;
 <quote>Standard for Binary Floating-Point Arithmetic</quote>,
 except that &clisp; does not support features like
 <literal>&plusmn;0</literal>, <literal>&plusmn;inf</literal>,
 <literal>NaN</literal>, gradual underflow, etc.
 &cl; does not make use of these features, so, to reduce portability
 problems, &clisp; by design returns the same floating point results on
 all platforms (&clisp; has a floating-point emulation built in for
 platforms that do not support &ieee-bfp;).  Note that
 <itemizedlist><listitem><simpara>When you got a <literal>NaN</literal>
    in your program, your program is broken, so you will spend time
    determining where the <literal>NaN</literal> came from.
    It is better to &signal; an &error-t; in this case.</simpara></listitem>
  <listitem><simpara>When you got unnormalized floats in your program,
    your results will have a greatly reduced accuracy anyway.
    Since &clisp; has the means to cope with this - &long-float-t;s of
    <link linkend="lfd">variable precision</link> - it does not
    need unnormalized floats.</simpara></listitem></itemizedlist>
 This is why &features-my; does not contain the
 <constant>:IEEE-FLOATING-POINT</constant> keyword.</para>

<formalpara id="lfd"><title>Arbitrary Precision Floats</title>
<para>&long-float-t;s have variable mantissa length, which is a
 multiple of 16 (or 32, depending on the word size of the processor).
 The default length used when &long-float-t;s are &read; is given by the
 &place; &lfd-l;.  It can be set by <code>(&setf; (&lfd;) &n-r;)</code>,
 where &n-r; is a positive &integer-t;.  E.g., <code>(&setf; (&lfd;)
 3322)</code> sets the default precision of &long-float-t;s to about
 1000 decimal digits.</para></formalpara>


<section id="flocont"><title>Rule of Float Precision Contagion
  <ulink role="clhs" url="sec_12-1-4-4"/></title>

<para>The floating point contagion is controlled by the variable
 &flocont;.  When it is non-&nil;, contagion is done as per the
 &ansi-cl;: &short-float-t; &rarr; &single-float-t; &rarr;
 &double-float-t; &rarr; &long-float-t;.</para>

<variablelist>
<varlistentry><term>Rationale:</term>
 <listitem><simpara>See it pragmatically: save what you can and let
  others worry about the rest.</simpara></listitem></varlistentry>
<varlistentry><term>Brief:</term>
 <listitem><simpara>&cl; knows the number's <emphasis>precision</emphasis>,
   not <emphasis>accuracy</emphasis>, so preserving the precision can be
   accomplished reliably, while anything relating to the accuracy is
   just a speculation - only the user (programmer) knows what it is in
   each case.</simpara></listitem></varlistentry>
<varlistentry><term>Detailed:</term>
 <listitem><simpara>A computer float is an approximation of a real number.
  One can think of it as a random variable with the mean equal to
  itself and standard deviation equal to half the last significant digit.
  E.g., <literal>1.5</literal> is actually <literal>1.5&plusmn;0.05</literal>.
  Consider adding <literal>1.5</literal> and <literal>1.75</literal>.
  &ansi-cl; requires that <code>(&plus; 1.5 1.75)</code>
  return <returnvalue>3.25</returnvalue>, while traditional &clisp;
  would return <returnvalue>3.3</returnvalue>.
  The implied random variables are: <literal>3.25&plusmn;0.005</literal>
  and <literal>3.3&plusmn;0.05</literal>.
  Note that the traditional &clisp; way <emphasis role="strong">does</emphasis>
  lie about the mean: the mean &is-e; <literal>3.25</literal> and
  nothing else, while the standard way
  <emphasis role="strong">could</emphasis> be lying about the deviation
  (accuracy): if the implied accuracy of <literal>1.5</literal> (i.e., 0.05)
  is its actual accuracy, then the accuracy of the result cannot be
  smaller that that.  Therefore, since &cl; has no way of knowing the
  actual accuracy, &ansi-cl; (and all the other standard engineering
  programming languages, like &c-lang;, <command role="dict">Fortran</command>
  etc) decided that keeping the accuracy correct is the business of the
  programmer, while the language should preserve what it can - the precision.
  </simpara></listitem></varlistentry>
<varlistentry><term>Experience:</term>
  <listitem><simpara>Rounding errors accumulate, and if a computation
  is conducted with insufficient precision, an outright incorrect
  result can be returned.
  (E.g., <code>E(x<superscript>2</superscript>) -
  E(x)<superscript>2</superscript></code> can be negative!)
  The user should not mix floats of different precision (that's what
  &warn-fpc; is for), but one should not be penalized for this too
  harshly.</simpara></listitem></varlistentry>
</variablelist>

<para>When &flocont; is &nil;, the traditional &clisp; method is used,
 namely the result of an arithmetic operation whose arguments are of
 different float types is rounded to the float format of the shortest
 (least precise) of the arguments: &rational-t; &rarr;
 &long-float-t; &rarr; &double-float-t; &rarr; &single-float-t;
 &rarr; &short-float-t; (in contrast to
 <ulink role="clhs" url="sec_12-1-4-4"/>!)</para>

<variablelist>
<varlistentry><term>Rationale:</term>
 <listitem><simpara>See it mathematically.  Add intervals:
  <code>{1.0 &plusmn; 1e-8} + {1.0 &plusmn; 1e-16} = {2.0 &plusmn;
  1e-8}</code>.  So, if we add <literal>1.0s0</literal> and
  <literal>1.0d0</literal>, we should get <literal>2.0s0</literal>.
  </simpara></listitem></varlistentry>
<varlistentry><term>Brief:</term>
 <listitem><simpara>Do not suggest high accuracy of a result by giving
  it a precision that is greater than its accuracy.
  </simpara></listitem></varlistentry>
<varlistentry><term>Example:</term>
 <listitem><simpara><code>(&subt; (&plus; 1.7 &pi-v;) &pi-v;)</code>
  should not return <returnvalue>1.700000726342836417234L0</returnvalue>,
   it should return <returnvalue>1.7f0</returnvalue> (or
   <returnvalue>1.700001f0</returnvalue> if there were rounding errors).
</simpara></listitem></varlistentry>
<varlistentry><term>Experience:</term>
 <listitem><simpara>If in a computation using thousands of &short-float-t;s,
  a &long-float-t; (like &pi-v;) happens to be used, the long precision
  should not propagate throughout all the intermediate values.
  Otherwise, the long result would look precise, but its accuracy is
  only that of a &short-float-t;; furthermore much computation time
  would be lost by calculating with &long-float-t;s when only
  &short-float-t;s would be needed.</simpara></listitem></varlistentry>
</variablelist>

<simplesect id="warn-fpc"><title>Variable &warn-fpc;</title>
<para>If the variable &warn-fpc; is non-&nil;, a &warning-t; is emitted for
 every coercion involving different floating-point types.
 As explained above, float precision contagion is not a good idea.
 You can avoid the contagion by doing all your computations with the
 same floating-point type (and using &float; to convert all constants,
 e.g., &pi-v;, to your preferred type).</para>
<para>This variable helps you eliminate all occurrences of float
 precision contagion: set it to &t; to have &clisp; &signal; a
 &warning-t; on float precision contagion; set it to &error; to have
 &clisp; &signal; an &error-t; on float precision contagion, so that you
 can look at the stack &backtrace;.</para></simplesect>

</section>

<section id="floratcont"><title>Rule of Float and Rational Contagion
  <ulink role="clhs" url="sec_12-1-4-1"/></title>

<para>The contagion between floating point and rational numbers is controlled
 by the variable &floratcont;.  When it is non-&nil;, contagion is done as per
 the &ansi-cl;: &rational-t; &rarr; &float-t;.</para>

<para>When &floratcont; is &nil;, the traditional &clisp; method is used,
 namely if the result is mathematically an exact rational number, this
 rational number is returned (in contrast to
 <ulink role="clhs" url="sec_12-1-4-1"/>!)</para>

<para>&floratcont; has an effect only in those few cases when the mathematical
 result is exact although one of the arguments is a floating-point number,
 such as <code>(&star; 0 1.618)</code>, <code>(&slash; 0 1.618)</code>,
 <code>(&atan; 0 1.0)</code>, <code>(&expt; 2.0 0)</code>,
 <code>(&phase; 2.718)</code>.</para>

<simplesect id="warn-fprc"><title>Variable &warn-fprc;</title>
<para>If the variable &warn-fprc; is non-&nil;, a &warning-t; is emitted for
 every avoidable coercion from a rational number to a floating-point number.
 You can avoid such coercions by calling &float; to convert the particular
 rational numbers to your preferred floating-point type.</para>
<para>This variable helps you eliminate all occurrences of avoidable
 coercions to a floating-point number when a rational number result
 would be possible: set it to &t; to have &clisp; &signal; a &warning-t;
 in such situations; set it to &error; to have &clisp; &signal; an
 &error-t; in such situations, so that you can look at the stack
 &backtrace;.</para></simplesect>

<simplesect id="phasecont"><title>Variable &phasecont;</title>
<para>A similar variable, &phasecont;, controls the return
 value of &phase; when the argument is an exact nonnegative &real-t;.
 Namely, if &phasecont; is non-&nil;, it returns a floating-point zero;
 if &phasecont; is &nil;, it returns an exact zero.  Example:
 <code>(&phase; 2/3)</code></para></simplesect>

</section>
</section>

<section id="complex-comp"><title>Complex Computations
  <ulink role="clhs" url="sec_12-1-5"/></title>

<para>Complex numbers can have a real part and an imaginary part of
 different types. For example, <code>(&sqrt; -9.0)</code> evaluates to
 the number <literal role="data">&sharp-C;(0 3.0)</literal>,
 which has a real part of exactly &zero;,
 not only <literal role="data">0.0</literal>
 (which would mean <quote>approximately 0</quote>).</para>

<para>The &typespec-glo; for this is <literal role="type">(&complex-t;
  &integer-t; &single-float-t;)</literal>, and <literal role="type">(&complex-t;
  <varname>type-of-real-part</varname>
  <varname>type-of-imaginary-part</varname>)</literal> in general.</para>

<para>The &typespec-glo; <literal role="type">(&complex-t;
  &type-r;)</literal> is equivalent to <literal role="type">(&complex-t;
  &type-r; &type-r;)</literal>.</para>

</section>

<section id="complex-rational"><title>Rule of Canonical Representation
  for Complex Rationals <ulink role="clhs" url="sec_12-1-5-3"/></title>

<para>Complex numbers can have a real part and an imaginary part of
 different types.  If the imaginary part is &eql; to &zero;,
 the number is automatically converted to a real number.</para>

<para>This has the advantage that
 <code>(&let; ((x (&sqrt; -9.0))) (* x x))</code> - instead of
 evaluating to <literal role="data">&sharp-C;(-9.0 0.0)</literal>,
 with &x-r; = <literal role="data">&sharp-C;(0.0 3.0)</literal> -
 evaluates to <literal role="data">&sharp-C;(-9.0 0)</literal> =
 <literal role="data">-9.0</literal>,
 with &x-r; = <literal role="data">&sharp-C;(0 3.0)</literal>.</para>

</section>

<section id="random-state"><title>Random-State Operations
  <ulink role="clhs" url="sec_12-1-7"/></title>
<para>To ease reproducibility, the variable &random-state-var; is
 initialized to the same value on each invocation, so that
 <screen>&sh-prompt; &clisp-cmd; &opt-norc; &opt-x; '(&random; 1s0)'</screen>
 will always print the same number.</para>
<para>If you want a new random state on each invocation, you can arrange
 for that by using &init-function;: <screen>
&sh-prompt; &clisp-cmd; &opt-norc; &opt-x; '(&savemem; "foo" :init-function (&lambda-m; () (&setq; &random-state-var; (&make-random-state; &t;))))'
&sh-prompt; &clisp-cmd; &opt-norc; &opt-M; foo.mem &opt-x; '(&random; 1s0)'</screen>
 or by placing <code>(&setq; &random-state-var;
    (&make-random-state; &t;))</code> into your &RC-file;.</para>
</section>
</section>

</chapter>

<chapter id="characters"><title>Characters
  <ulink role="clhs" url="chap-13"/></title>

<section id="char-intro"><title>Introduction to Characters
  <ulink role="clhs" url="sec_13-1"/></title>

<section id="char-code"><title>Function &char-code;</title>

<para>&char-code; takes values from &zero; (inclusive) to
 &char-code-limit; (exclusive), i.e., the implementation
 supports exactly &char-code-limit; characters.</para>

<table id="char-code-limit-table" frame="all">
 <title>Number of characters</title>
 <tgroup cols="3" colsep="1" rowsep="1" align="center">
 <thead><row><entry>binaries built</entry>
             <entry>&without; &unicode; support</entry>
             <entry>&with; &unicode; support</entry></row></thead>
 <tbody><row><entry>&char-code-limit;</entry>
             <entry>2<superscript>8</superscript> = 256</entry>
             <entry>17 * 2<superscript>16</superscript> = 1114112</entry></row>
</tbody></tgroup></table>
</section>

<section id="base-char"><title>Type &base-char-t;</title>
<para>The types <classname>EXT:STRING-CHAR</classname> and
 &base-char-t; are equivalent to &character-t;.
 <classname>EXT:STRING-CHAR</classname> used to be available as
 <classname>STRING-CHAR</classname> prior to removal from &ansi-cl; by
 &iss026;.</para>
</section>

<section id="char-width"><title>Function &char-width;</title>
<para><code>(&char-width; &ch-r;)</code> returns the number of screen
 columns occupied by &ch-r;.  The value is <variablelist>
  <varlistentry><term>0</term><listitem><simpara>for non-spacing
     characters (such as control characters and many combining
     characters);</simpara></listitem></varlistentry>
  <varlistentry><term>2</term><listitem><simpara>for double-width East
     Asian characters;</simpara></listitem></varlistentry>
  <varlistentry><term>1</term><listitem><simpara>for all other
     characters.</simpara></listitem></varlistentry></variablelist>
 See also function &string-width;.
</para></section>
</section>

<section id="char-sets"><title>Character sets</title>

<para>The characters are ordered according to a superset of the
 &charset-ascii;.</para>

<!-- #ifdef ENABLE_UNICODE -->
<variablelist><varlistentry><term>&unicode-only;</term>
<listitem><simpara>More precisely, &clisp; uses the 21-bit &unicode32;
 character set (ISO 10646, also known as UCS-4).
</simpara></listitem></varlistentry></variablelist>
<!-- #endif -->

<!-- #if defined(ISOLATIN_CHS) && !defined(ENABLE_UNICODE) -->
<variablelist><varlistentry><term>&non-unicode-only;</term>
<listitem><para>More precisely, &clisp; uses the ISO Latin-1 (ISO
 8859-1) character set:
<informaltable id="latin-1-table" frame="all">
  <tgroup cols="17" colsep="1" rowsep="1" align="center">
  &char-table-header;<tbody>
  <row><entry>#x00</entry>&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;
   &cc;&cc;&cc;&cc;&cc;</row>
  <row><entry>#x10</entry>&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;&cc;
   &cc;&cc;&cc;&cc;&cc;</row>
  &ascii-printable;
  <row><entry>#x80</entry><entry/><entry/><entry/>
   <entry/><entry/><entry/><entry/><entry>
   </entry><entry/><entry/><entry/><entry/>
   <entry/><entry/><entry/><entry/></row>
  <row><entry>#x90</entry><entry/><entry/><entry/>
   <entry/><entry/><entry/><entry/><entry>
   </entry><entry/><entry/><entry/><entry/>
   <entry/><entry/><entry/><entry/></row>
  <row><entry>#xA0</entry><entry>&nbsp;</entry><entry>&iexcl;</entry>
   <entry>&cent;</entry><entry>&pound;</entry><entry>&curren;</entry>
   <entry>&yen;</entry><entry>&brvbar;</entry><entry>&sect;</entry>
   <entry>&uml;</entry><entry>&copy;</entry><entry>&ordf;</entry>
   <entry>&laquo;</entry><entry>&not;</entry><entry>&shy;</entry>
   <entry>&reg;</entry><entry>&macr;</entry></row>
  <row><entry>#xB0</entry><entry>&deg;</entry><entry>&plusmn;</entry>
   <entry>&sup2;</entry><entry>&sup3;</entry><entry>&acute;</entry>
   <entry>&micro;</entry><entry>&para;</entry><entry>&middot;</entry>
   <entry>&cedil;</entry><entry>&sup1;</entry><entry>&ordm;</entry>
   <entry>&raquo;</entry><entry>&frac14;</entry><entry>&frac12;</entry>
   <entry>&frac34;</entry><entry>&iquest;</entry></row>
  <row><entry>#xC0</entry><entry>&Agrave;</entry><entry>&Aacute;</entry>
   <entry>&Acirc;</entry><entry>&Atilde;</entry><entry>&Auml;</entry>
   <entry>&Aring;</entry><entry>&AElig;</entry><entry>&Ccedil;</entry>
   <entry>&Egrave;</entry><entry>&Eacute;</entry><entry>&Ecirc;</entry>
   <entry>&Euml;</entry><entry>&Igrave;</entry><entry>&Iacute;</entry>
   <entry>&Icirc;</entry><entry>&Iuml;</entry></row>
  <row><entry>#xD0</entry><entry>&ETH;</entry><entry>&Ntilde;</entry>
   <entry>&Ograve;</entry><entry>&Oacute;</entry><entry>&Ocirc;</entry>
   <entry>&Otilde;</entry><entry>&Ouml;</entry><entry>&times;</entry>
   <entry>&Oslash;</entry><entry>&Ugrave;</entry><entry>&Uacute;</entry>
   <entry>&Ucirc;</entry><entry>&Uuml;</entry><entry>&Yacute;</entry>
   <entry>&THORN;</entry><entry>&szlig;</entry></row>
  <row><entry>#xE0</entry><entry>&agrave;</entry><entry>&aacute;</entry>
   <entry>&acirc;</entry><entry>&atilde;</entry><entry>&auml;</entry>
   <entry>&aring;</entry><entry>&aelig;</entry><entry>&ccedil;</entry>
   <entry>&egrave;</entry><entry>&eacute;</entry><entry>&ecirc;</entry>
   <entry>&euml;</entry><entry>&igrave;</entry><entry>&iacute;</entry>
   <entry>&icirc;</entry><entry>&iuml;</entry></row>
  <row><entry>#xF0</entry><entry>&eth;</entry><entry>&ntilde;</entry>
   <entry>&ograve;</entry><entry>&oacute;</entry><entry>&ocirc;</entry>
   <entry>&otilde;</entry><entry>&ouml;</entry><entry>&divide;</entry>
   <entry>&oslash;</entry><entry>&ugrave;</entry><entry>&uacute;</entry>
   <entry>&ucirc;</entry><entry>&uuml;</entry><entry>&yacute;</entry>
   <entry>&thorn;</entry><entry>&yuml;</entry></row>
</tbody></tgroup></informaltable>
&char-table-legend;
</para></listitem></varlistentry></variablelist>
<!-- #endif -->

<table id="standard-char-table" frame="all">
  <title>Standard characters</title>
 <tgroup cols="2" colsep="1" rowsep="1" align="center">
  &char-code-header;<tbody>
 <row><entry><keysym>#\Space</keysym></entry>
              <entry><keycode>#x20</keycode></entry></row>
 <row><entry>&nl-s;</entry><entry><keycode>#x0A</keycode></entry></row>
</tbody></tgroup></table>

<table id="semi-standard-char-table" frame="all">
  <title>Semi-standard characters</title>
 <tgroup cols="2" colsep="1" rowsep="1" align="center">
  &char-code-header;<tbody>
 <row><entry><keysym>#\Backspace</keysym></entry>
              <entry><keycode>#x08</keycode></entry></row>
 <row><entry><keysym>#\Tab</keysym></entry>
              <entry><keycode>#x09</keycode></entry></row>
 <row><entry>&lf-s;</entry><entry><keycode>#x0A</keycode></entry></row>
 <row><entry><keysym>#\Page</keysym></entry>
              <entry><keycode>#x0C</keycode></entry></row>
 <row><entry>&cr-s;</entry><entry><keycode>#x0D</keycode></entry></row>
</tbody></tgroup></table>

<para>&nl-s; is the &line-term;.</para>

<table id="extra-named-chars-table" frame="all">
  <title>Additional Named Characters</title>
 <tgroup cols="2" colsep="1" rowsep="1" align="center">
  &char-code-header;<tbody>
 <row><entry><keysym>#\Null</keysym></entry>
              <entry><keycode>#x00</keycode></entry></row>
 <row><entry><keysym>#\Bell</keysym></entry>
              <entry><keycode>#x07</keycode></entry></row>
 <row><entry><keysym>#\Escape</keysym></entry>
              <entry><keycode>#x1B</keycode></entry></row>
</tbody></tgroup></table>

<table id="ctrl-char-table" frame="all">
  <title>Additional syntax for characters with code from
   <keycode>#x00</keycode> to <keycode>#x1F</keycode>:</title>
 <tgroup cols="2" colsep="1" rowsep="1" align="center">
  &char-code-header;<tbody>
 <row><entry><keysym>#\^@</keysym></entry>
              <entry><keycode>#x00</keycode></entry></row>
 <row><entry><keysym>#\^A</keysym> &hellip; <keysym>#\^Z</keysym></entry>
              <entry><keycode>#x01</keycode> &hellip;
                   <keycode>#x1A</keycode></entry></row>
 <row><entry><keysym>#\^[</keysym></entry>
              <entry><keycode>#x1B</keycode></entry></row>
 <row><entry><keysym>#\^\</keysym></entry>
              <entry><keycode>#x1C</keycode></entry></row>
 <row><entry><keysym>#\^]</keysym></entry>
              <entry><keycode>#x1D</keycode></entry></row>
 <row><entry><keysym>#\^^</keysym></entry>
              <entry><keycode>#x1E</keycode></entry></row>
 <row><entry><keysym>#\^_</keysym></entry>
              <entry><keycode>#x1F</keycode></entry></row>
</tbody></tgroup></table>

<para>See also <xref linkend="sharpsign-backslash"/>.</para>

</section>

<section id="char-script"><title>Character Scripts
  <ulink role="clhs" url="sec_13-1-2-1"/></title>

<para>The only defined character script is the type &character-t;
 itself.</para>

</section>

<section id="char-attrib"><title>Character Attributes
  <ulink role="clhs" url="sec_13-1-3"/></title>

<para>Characters have no implementation-defined or &cltl1; font and bit
 attributes.  All characters are simple characters.</para>

<section id="input-char"><title>Input Characters</title>

<para>For backward compatibility, there is a class &input-char;
 representing either a character with font and bits, or a keystroke.
 The following functions work with objects of types &character-t;
 and &input-char;.
 Note that &eql; or &equal; are equivalent to &eq; on objects of type
 &input-char;.</para>

<variablelist>
 <varlistentry><term><constant>EXT:CHAR-FONT-LIMIT</constant> = 16</term>
  <listitem><simpara>The system uses only font 0.
  </simpara></listitem></varlistentry>
 <varlistentry><term><constant>EXT:CHAR-BITS-LIMIT</constant> = 16</term>
  <listitem><para>Character bits:
    <informaltable id="bit-table" frame="all">
     <tgroup cols="2" colsep="1" rowsep="1" align="center">
      &key-value-header;<tbody>
       <row><entry>&control-k;</entry><entry>&ch-ctrl;</entry></row>
       <row><entry>&meta-k;</entry><entry>&ch-meta;</entry></row>
       <row><entry>&super-k;</entry><entry>&ch-super;</entry></row>
       <row><entry>&hyper-k;</entry><entry>&ch-hyper;</entry></row>
 </tbody></tgroup></informaltable></para></listitem></varlistentry>
 <varlistentry><term><code>(<function>EXT:CHAR-FONT</function>
  &object-r;)</code></term>
 <listitem><simpara>returns the font of a &character-t; or &input-char;.
  </simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>EXT:CHAR-BITS</function>
  &object-r;)</code></term>
 <listitem><simpara>returns the bits of a &character-t; or &input-char;.
  </simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>EXT:MAKE-CHAR</function>
     &ch-r; [<replaceable>bits</replaceable>
            [<replaceable>font</replaceable>]])</code></term>
 <listitem><simpara>returns a new &input-char;, or &nil; if such a
 character cannot be created.</simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>EXT:CHAR-BIT</function>
  &object-r; &name-r;)</code></term>
 <listitem><simpara>returns &t; if the named bit is set in &object-r;,
  else &nil;.</simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>EXT:SET-CHAR-BIT</function>
  &object-r; &name-r; &nval-r;)</code></term>
 <listitem><simpara>returns a new &input-char; with the named bit set or
   unset, depending on the &boolean-t; &nval-r;.
 </simpara></listitem></varlistentry>

</variablelist>

<warning><para>&input-char; is &not-e; a subtype of
  &character-t;.</para></warning>

<!-- #ifdef KEYBOARD -->
<variablelist>
<varlistentry><term>&unix-w32-only;</term>
<listitem><simpara>The system itself uses this &input-char; type only to
 mention special keys and &ctrl;/&alt;/&shift; key status on return from
 <code>(&read-char; &kbd-in;)</code>.</simpara></listitem></varlistentry>
</variablelist>
<!-- #endif -->

</section>

</section>

<section id="graph-char"><title>Graphic Characters
  <ulink role="clhs" url="sec_13-1-4-1"/></title>

<para>The &graphic; characters are those &unicode; characters which are
 defined by the &unicode; standard, excluding the ranges
 <keycode>U0000</keycode> &hellip; <keycode>U001F</keycode> and
 <keycode>U007F</keycode> &hellip; <keycode>U009F</keycode>.</para>

</section>

<section id="alpha-char"><title>Alphabetic Characters
  <ulink role="clhs" url="sec_13-1-4-2"/></title>

<para>The alphabetic characters are those &unicode; characters which are
 defined as letters by the &unicode; standard, e.g., the &ascii; characters
<literallayout><literal>             ABCDEFGHIJKLMNOPQRSTUVWXYZ
             abcdefghijklmnopqrstuvwxyz</literal></literallayout>
and the international alphabetic characters from the character set:
<literallayout><literal>             &Ccedil;&uuml;&eacute;&acirc;&auml;&agrave;&aring;&ccedil;&ecirc;&euml;&egrave;&iuml;&icirc;&igrave;&Auml;&Aring;&Eacute;&aelig;&AElig;&ocirc;&ouml;&ograve;&ucirc;&ugrave;&yuml;&Ouml;&Uuml;&szlig;&aacute;&iacute;&oacute;&uacute;&ntilde;&Ntilde;&ordf;&ordm;&atilde;&otilde;&Oslash;&oslash;&Agrave;&Atilde;&Otilde;</literal></literallayout>
etc.</para>
</section>

<section id="char-case"><title>Characters With Case
  <ulink role="clhs" url="sec_13-1-4-3"/></title>

<section id="char-invertcase"><title>Function &char-invertcase;</title>
<para><code>(&char-invertcase; &ch-r;)</code> returns the corresponding
 character in the other case for &char;, i.e., &char-upcase; for a
 lowercase character and &char-downcase; for an uppercase character; for
 a character that does not have a case attribute, the argument is returned.
 See also &string-invertcase; and &nstring-invertcase;.</para></section>

<section id="char-ext"><title>Case of Implementation-Defined Characters
  <ulink role="clhs" url="sec_13-1-4-3-4"/></title>

<para>The characters with case are those &unicode; characters &c-r;, for
 which the upper case mapping &uc-r; and the lower case mapping &lc-r;
 have the following properties:
<itemizedlist>
  <listitem><simpara>&uc-r; and &lc-r; are different</simpara></listitem>
  <listitem><simpara>&c-r; is one of &uc-r; and &lc-r;</simpara></listitem>
  <listitem><simpara>the upper case mapping of &uc-r; and of &lc-r;
   is &uc-r;</simpara></listitem>
  <listitem><simpara>the lower case mapping of &uc-r; and of &lc-r;
   is &lc-r;</simpara></listitem>
</itemizedlist></para>

<para>The titlecase property of &unicode; characters has no equivalent in
 &cl;.</para>

</section>

</section>

<section id="num-char"><title>Numeric Characters
  <ulink role="clhs" url="sec_13-1-4-4"/></title>

<para>The numeric characters are those &unicode; characters which are
 defined as digits by the &unicode; standard.</para>

</section>

<section id="char-ord"><title>Ordering of Characters
  <ulink role="clhs" url="sec_13-1-6"/></title>

<para>The characters are ordered according to their &unicode; code.</para>

<para>The functions &char-equal; &char-not-equal;, &char-lessp;,
 &char-greaterp;, &char-not-greaterp;, &char-not-lessp; ignore bits and
 font attributes of their arguments.</para>

</section>

<section id="clhs-newline"><title>Treatment of Newline during Input and Output
  <ulink role="clhs" url="sec_13-1-8"/></title>

<para>Newlines are written according to the stream's &encoding;, see the
 function &stream-external-format; and the description of &encoding;s,
 in particular, &line-term;s.
 The default behavior is as follows:</para>

<!-- #if defined(WIN32) || (defined(UNIX) && (O_BINARY != 0)) -->
<variablelist>
<varlistentry><term>&win32-only;</term>
<listitem><simpara>When writing to a file, &nl-s; is converted to
 &cr-c;/&lf-c;. (This is the usual convention on &dos;.)
 For example, &cr-s;+&nl-s; is written as &cr-c;/&cr-c;/&lf-c;.
</simpara></listitem></varlistentry></variablelist>
<!-- #endif -->

<para>When reading from a file, &cr-c;/&lf-c; is converted to &nl-s;
 (the usual convention on &dos;), and &cr-c; not followed by &lf-c; is
 converted to &nl-s; as well (the usual conversion on MacOS, also used
 by some programs on &win32;).
 If you do not want this, i.e., if you really want to distinguish
 &lf-c;, &cr-c; and &cr-c;/&lf-c;, you have to resort to
 binary input (function &read-byte;).</para>

<formalpara><title>Justification</title>
<para><ulink url="http://www.unicode.org/reports/tr13/tr13-9.html">Unicode
  Newline Guidelines</ulink> say: <quote>Even if you know which
  characters represents NLF on your particular platform, on input and in
  interpretation, treat CR, LF, CRLF, and NEL the same. Only on output do
  you need to distinguish between them.</quote></para></formalpara>

<formalpara><title>Rationale</title>
<para>In &clisp;, &nl-s; is identical to &lf-s;
 (which is specifically permitted by the &ansi-cl; in
 <ulink role="clhs" url="sec_13-1-7"/> <quote>Character Names</quote>).
 Consider a file containing exactly this string:
 <code>(&concatenate; '&string-any; "foo" (&string; &lf-s;)
  "bar" (&string; &cr-s;) (&string; &lf-s;))</code>
 Suppose we open it with <code>(&open; "foo" &extfmt; &dos-k;)</code>.
 What should &read-line; return?
 Right now, it returns <returnvalue>"foo"</returnvalue>
 (the second &read-line; returns <returnvalue>"bar"</returnvalue>
 and reaches &eos;).
 If our i/o were <quote>faithful</quote>, &read-line; would have
 returned the string <code>(&concatenate; '&string-any; "foo" (&string;
  &lf-s;) "bar")</code>, i.e., a string with an embedded &nl-s;
 between <returnvalue>"foo"</returnvalue>
 and <returnvalue>"bar"</returnvalue> (because a single &lf-s; is not a
 &nl-s; in the specified &extfmt;, it will not make &read-line; return,
 but it &is-e; a &clisp; &nl-s;!)  Even though the specification for
 &read-line; does not explicitly forbids newlines inside the returned
 string, such behavior would be quite surprising, to say the least.
 Moreover, this line (with an embedded &nl-s;) would be written as two
 lines (when writing to a &stream-t; with &extfmt; of &dos-k;), because
 the embedded &nl-s; would be written as &cr-c;+&lf-c;.</para></formalpara>

</section>

<section id="char-int"><title>Character Encodings
  <ulink role="clhs" url="sec_13-1-9"/></title>

<para>The integer returned by &char-int; is the same as the character's
 code (&char-code;).</para>

</section>

<section id="script-ext"><title>Documentation of Implementation-Defined Scripts
  <ulink role="clhs" url="sec_13-1-10"/></title>

<para>See <xref linkend="encoding"/>.</para>

</section>

<section id="char-platform-dep"><title>Platform-Dependent Characters</title>

<para>The characters that are not &graphic; chars and the space character
 have names:</para>

<!-- #ifdef WIN32_CHARNAMES -->
<table id="dos-win32-chars-table" frame="all">
 <title>Additional characters (&win32-only;)</title>
 <tgroup cols="2" colsep="1" rowsep="1" align="center">
  &code-char-header;<tbody>
 <row><entry><code>(&code-char; #x00)</code></entry>
          <entry><keysym>#\Null</keysym></entry></row>
 <row><entry><code>(&code-char; #x07)</code></entry>
          <entry><keysym>#\Bell</keysym></entry></row>
 <row><entry><code>(&code-char; #x08)</code></entry>
          <entry><keysym>#\Backspace</keysym></entry></row>
 <row><entry><code>(&code-char; #x09)</code></entry>
          <entry><keysym>#\Tab</keysym></entry></row>
 <row><entry><code>(&code-char; #x0A)</code></entry>
          <entry>&nl-s;</entry><entry>&lf-s;</entry></row>
 <row><entry><code>(&code-char; #x0B)</code></entry>
          <entry><keysym>#\Code11</keysym></entry></row>
 <row><entry><code>(&code-char; #x0C)</code></entry>
          <entry><keysym>#\Page</keysym></entry></row>
 <row><entry><code>(&code-char; #x0D)</code></entry>
          <entry>&cr-s;</entry></row>
 <row><entry><code>(&code-char; #x1A)</code></entry>
          <entry><keysym>#\Code26</keysym></entry></row>
 <row><entry><code>(&code-char; #x1B)</code></entry>
          <entry><keysym>#\Escape</keysym></entry>
          <entry><keysym>#\Esc</keysym></entry></row>
 <row><entry><code>(&code-char; #x20)</code></entry>
          <entry><keysym>#\Space</keysym></entry></row>
 <row><entry><code>(&code-char; #x7F)</code></entry>
          <entry><keysym>#\Rubout</keysym></entry></row>
</tbody></tgroup></table>
<!-- #endif -->

<!-- #ifdef UNIX_CHARNAMES -->
<table id="unix-chars-table" frame="all">
 <title>Additional characters (&unix-only;)</title>
 <tgroup cols="2" colsep="1" rowsep="1" align="center">
  &code-char-header;<tbody>
 <row><entry><code>(&code-char; #x00)</code></entry>
          <entry><keysym>#\Null</keysym></entry>
          <entry><keysym>#\Nul</keysym></entry></row>
 <row><entry><code>(&code-char; #x01)</code></entry>
          <entry><keysym>#\Soh</keysym></entry></row>
 <row><entry><code>(&code-char; #x02)</code></entry>
          <entry><keysym>#\Stx</keysym></entry></row>
 <row><entry><code>(&code-char; #x03)</code></entry>
          <entry><keysym>#\Etx</keysym></entry></row>
 <row><entry><code>(&code-char; #x04)</code></entry>
          <entry><keysym>#\Eot</keysym></entry></row>
 <row><entry><code>(&code-char; #x05)</code></entry>
          <entry><keysym>#\Enq</keysym></entry></row>
 <row><entry><code>(&code-char; #x06)</code></entry>
          <entry><keysym>#\Ack</keysym></entry></row>
 <row><entry><code>(&code-char; #x07)</code></entry>
          <entry><keysym>#\Bell</keysym></entry>
          <entry><keysym>#\Bel</keysym></entry></row>
 <row><entry><code>(&code-char; #x08)</code></entry>
          <entry><keysym>#\Backspace</keysym></entry>
          <entry><keysym>#\Bs</keysym></entry></row>
 <row><entry><code>(&code-char; #x09)</code></entry>
          <entry><keysym>#\Tab</keysym></entry>
          <entry><keysym>#\Ht</keysym></entry></row>
 <row><entry><code>(&code-char; #x0A)</code></entry>
          <entry>&nl-s;</entry>
          <entry><keysym>#\Nl</keysym></entry><entry>&lf-s;</entry></row>
 <row><entry><code>(&code-char; #x0B)</code></entry>
          <entry><keysym>#\Vt</keysym></entry></row>
 <row><entry><code>(&code-char; #x0C)</code></entry>
          <entry><keysym>#\Page</keysym></entry>
          <entry><keysym>#\Np</keysym></entry></row>
 <row><entry><code>(&code-char; #x0D)</code></entry>
          <entry>&cr-s;</entry>
          <entry><keysym>#\Cr</keysym></entry></row>
 <row><entry><code>(&code-char; #x0E)</code></entry>
          <entry><keysym>#\So</keysym></entry></row>
 <row><entry><code>(&code-char; #x0F)</code></entry>
          <entry><keysym>#\Si</keysym></entry></row>
 <row><entry><code>(&code-char; #x10)</code></entry>
          <entry><keysym>#\Dle</keysym></entry></row>
 <row><entry><code>(&code-char; #x11)</code></entry>
          <entry><keysym>#\Dc1</keysym></entry></row>
 <row><entry><code>(&code-char; #x12)</code></entry>
          <entry><keysym>#\Dc2</keysym></entry></row>
 <row><entry><code>(&code-char; #x13)</code></entry>
          <entry><keysym>#\Dc3</keysym></entry></row>
 <row><entry><code>(&code-char; #x14)</code></entry>
          <entry><keysym>#\Dc4</keysym></entry></row>
 <row><entry><code>(&code-char; #x15)</code></entry>
          <entry><keysym>#\Nak</keysym></entry></row>
 <row><entry><code>(&code-char; #x16)</code></entry>
          <entry><keysym>#\Syn</keysym></entry></row>
 <row><entry><code>(&code-char; #x17)</code></entry>
          <entry><keysym>#\Etb</keysym></entry></row>
 <row><entry><code>(&code-char; #x18)</code></entry>
          <entry><keysym>#\Can</keysym></entry></row>
 <row><entry><code>(&code-char; #x19)</code></entry>
          <entry><keysym>#\Em</keysym></entry></row>
 <row><entry><code>(&code-char; #x1A)</code></entry>
          <entry><keysym>#\Sub</keysym></entry></row>
 <row><entry><code>(&code-char; #x1B)</code></entry>
          <entry><keysym>#\Escape</keysym></entry>
          <entry><keysym>#\Esc</keysym></entry></row>
 <row><entry><code>(&code-char; #x1C)</code></entry>
          <entry><keysym>#\Fs</keysym></entry></row>
 <row><entry><code>(&code-char; #x1D)</code></entry>
          <entry><keysym>#\Gs</keysym></entry></row>
 <row><entry><code>(&code-char; #x1E)</code></entry>
          <entry><keysym>#\Rs</keysym></entry></row>
 <row><entry><code>(&code-char; #x1F)</code></entry>
          <entry><keysym>#\Us</keysym></entry></row>
 <row><entry><code>(&code-char; #x20)</code></entry>
          <entry><keysym>#\Space</keysym></entry>
          <entry><keysym>#\Sp</keysym></entry></row>
 <row><entry><code>(&code-char; #x7F)</code></entry>
          <entry><keysym>#\Rubout</keysym></entry>
          <entry><keysym>#\Delete</keysym></entry>
          <entry><keysym>#\Del</keysym></entry></row>
</tbody></tgroup></table>
<!-- #endif -->

</section>

<section id="char-bits"><title>Obsolete Constants</title>

<table id="char-bits-table" frame="all">
  <title>Character bit constants (obsolete)</title>
 <tgroup cols="2" colsep="1" rowsep="1" align="center">
 <thead><row><entry>constant</entry><entry>value</entry></row></thead><tbody>
 <row><entry>&ch-ctrl;</entry><entry>1</entry></row>
 <row><entry>&ch-meta;</entry><entry>2</entry></row>
 <row><entry>&ch-super;</entry><entry>4</entry></row>
 <row><entry>&ch-hyper;</entry><entry>8</entry></row>
</tbody></tgroup></table>
</section>


</chapter>


<chapter id="conses"><title>Conses <ulink role="clhs" url="chap-14"/></title>

<section id="cons-list"><title>Conses as Lists
  <ulink role="clhs" url="sec_14-1-2"/></title>

<section id="map-func"><title>Mapping Functions</title>

<formalpara id="mapcap"><title>Function &mapcap;</title>
<para>The function &mapcap; is like &mapcan;, except that it
 concatenates the resulting lists with &append; instead of &nconc;:
<programlisting language="lisp">(&mapcap; &func-r; &x1-r; ... &xn-r;) &equiv;
(&apply; #'&append; (&mapcar; &func-r; &x1-r; ... &xn-r;))</programlisting>
(Actually a bit more efficient that this would have been.)</para></formalpara>

<formalpara id="maplap"><title>Function &maplap;</title>
<para>The function &maplap; is like &mapcon;, except that it
 concatenates the resulting lists with &append; instead of &nconc;:
 <programlisting language="lisp">(&maplap; &func-r; &x1-r; ... &xn-r;) &equiv;
(&apply; #'&append; (&maplist; &func-r; &x1-r; ... &xn-r;))</programlisting>
 (Actually a bit more efficient that this would have been.)</para></formalpara>

</section>
</section>
</chapter>


<chapter id="arrays"><title>Arrays <ulink role="clhs" url="chap-15"/></title>

<formalpara><title>Function &make-array;</title>
<para>&make-array; can return specialized arrays for the &array-element-type;s
 <literal role="type">(&unsigned-byte-t; 2)</literal>,
 <literal role="type">(&unsigned-byte-t; 4)</literal>,
 &ubyte-8;, &ubyte-16;, &ubyte-32;, and, of course, the required
 specializations &nil-t;, &bit-t; and &character-t;.</para></formalpara>

<formalpara><title>Function &adjust-array; for displaced arrays</title>
<para>An array to which another array is displaced should not be shrunk
 (using &adjust-array;) in such a way that the other array points into
 void space.  This cannot be checked at the time &adjust-array; is
 called!</para></formalpara>

<section id="array-elts"><title>Array Elements
  <ulink role="clhs" url="sec_15-1-1"/></title>

<table id="array-limit-table" frame="all"><title>Array limits</title>
 <tgroup cols="3" colsep="1" rowsep="1" align="center">&cpu-type-header;<tbody>
   <row><entry>&array-rank-limit;</entry>
    <entry namest="b32" nameend="b64" align="center"
           >2<superscript>12</superscript> = 4096</entry></row>
   <row><entry>&array-dimension-limit;</entry>
    <entry>2<superscript>24</superscript>-1 = 16777215</entry>
    <entry>2<superscript>32</superscript>-1 = 4294967295</entry></row>
   <row><entry>&array-total-size-limit;</entry>
    <entry>2<superscript>24</superscript>-1 = 16777215</entry>
    <entry>2<superscript>32</superscript>-1 = 4294967295</entry></row>
</tbody></tgroup></table></section>

</chapter>


<chapter id="strings"><title>Strings <ulink role="clhs" url="chap-16"/></title>

<section id="string-misc"><title>Miscellaneous</title>

<section id="string-comp"><title>String Comparison</title>
<para>String comparison (&string-lst; and friends) is based on the
 function &char-leq; (see <xref linkend="char-ord"/>).
 Therefore diphthongs do &not-e; obey the usual national rules.  Example:
 <literal>o &lt; oe &lt; z &lt; &ouml;</literal>.</para></section>

<section id="string-width"><title>Function &string-width;</title>
<para><code>(&string-width; &string-r; &key-amp; &start-r;
  &end-r;)</code> returns the number of screen columns occupied by
 &string-r;.  This is computed as the sum of all &char-width;s of all
 of the &string-r;'s characters:<programlisting language="lisp">
(&reduce; #'&plus; &string-r; &key-k; #'&char-width;)
</programlisting></para></section>

<section id="string-invertcase"><title>Functions &string-invertcase;
  and &nstring-invertcase;</title>
<para><code>(&string-invertcase; &string-r; &key-amp; &start-r; &end-r;)</code>
 and <code>(&nstring-invertcase; &string-r; &key-amp; &start-r; &end-r;)</code>
 are similar to &string-upcase; et al: they use &char-invertcase; to
 invert the case of each characters in the argument string region.</para>
</section>

</section>
</chapter>


<chapter id="sequences"><title>Sequences
  <ulink role="clhs" url="chap-17"/></title>

<section id="seq-func-ext"><title>Additional Functions</title>

<section id="trim-if"><title>Function <function>EXT:TRIM-IF</function></title>
<para>Function <code>(<function>EXT:TRIM-IF</function> &pred-r;
  &sequence-r;)</code> returns the portion of &sequence-r; without the
 leading and trailing elements which match &pred-r;.</para>
</section>

</section>

<section id="seq-macro-ext"><title>Additional Macros</title>

<section id="doseq"><title>Macro &doseq;</title>

<para>For iteration through a sequence, a macro &doseq;,
 similar to &dolist;, may be used instead of &map-f;:</para>

<programlisting language="lisp">
(&doseq; (&var-r; <replaceable>sequence-form</replaceable> [<replaceable>result-form</replaceable>])
  {&declaration-r;}*
  {&tag-r;|&form-r;}*)
</programlisting>

<para>&doseq; forms are &iter-form;s.</para>

</section>
</section>

<section id="nreverse-nreconc">
 <title>Functions &nreverse; &amp; &nreconc;</title>

<formalpara><title>Function &nreverse;</title>
<para>The result of &nreverse; is always &eq; to the argument.
 &nreverse; on a &vector-t; swaps pairs of elements.
 &nreverse; on a &list-t; swaps the first and the last
 element and reverses the list chaining between them.</para></formalpara>

<formalpara><title>Function &nreconc;</title>
<para>The result of &nreconc; is &eq; to the first argument unless it is
 &nil;, in which case the result is &eq; to the second argument.</para>
</formalpara>
</section>

<section id="rem-del"><title>Functions &remove; &amp; &delete;</title>

<para>&remove;, &remove-if;, &remove-if-not;, &remove-duplicates; return
 their argument unchanged, if no element has to be removed.</para>

<para>&delete;, &delete-if;, &delete-if-not;, &delete-duplicates;
 destructively modify their argument: If the argument is a &list-t;,
 the &cdr; parts are modified.  If the argument is a &vector-t; with
 fill pointer, the fill pointer is lowered and the remaining elements are
 compacted below the new fill pointer.</para>

<formalpara id="count-ansi"><title>Variable &count-ansi;</title>
<para>Contrary to the &ansi-cl; issue &iss283;,
 negative &count-k; keyword arguments are not allowed unless you set
 &count-ansi; to a non-&nil; value, in which case <quote>using a
 negative integer value is functionally equivalent to using a value of
 zero</quote>, as per the &ansi-cl; issue.</para></formalpara>

</section>

<section id="sorting"><title>Functions &sort; &amp; &stable-sort;</title>

<para>&sort; and &stable-sort; accept two additional keyword arguments
 &start-k; and &end-k;:</para>

<programlisting language="lisp">
(&sort; &sequence-r; &pred-r; &key-amp; &key-k; &start-k; &end-k;)
(&stable-sort; &sequence-r; &pred-r; &key-amp; &key-k; &start-k; &end-k;)
</programlisting>

<para>&sort; and &stable-sort; are identical.
 They implement the mergesort algorithm.
 Worst case complexity: <varname>O(n*log(n))</varname> comparisons,
 where &n-r; is the &length; of the subsequence bounded
 by the &start-k; and &end-k; arguments.</para>

</section>
</chapter>


<chapter id="hash"><title>Hash Tables <ulink role="clhs" url="chap-18"/></title>

<section id="hash-mod-key"><title>Modifying Hash Table Keys
  <ulink role="clhs" url="sec_18-1-2"/></title>
<para>If you <quote>visibly modify</quote> a key, consequences are
 <emphasis>unpredictable</emphasis>:<programlisting language="lisp">
(&let; ((&ht-r; (&make-hash-table; :test '&equalp;)))
  (&setf; (&gethash; &ht-r; &ht-r;) &t;)
  (&gethash; &ht-r; &ht-r;))
<computeroutput>&nil;</computeroutput> ;
<computeroutput>&nil;</computeroutput></programlisting>
 because <code>(&setf; &gethash;)</code> modifies &ht-r;, the very next
 &gethash; does &not-e; find it in itself.</para>
</section>

<section id="make-hash"><title>Function &make-hash-table;</title>

<para>&make-hash-table; accepts two additional keyword arguments
 <constant>:INITIAL-CONTENTS</constant> and <constant>:WEAK</constant>:</para>

<programlisting language="lisp">
(&make-hash-table; &key-amp; :TEST :INITIAL-CONTENTS :SIZE
                 :REHASH-SIZE :REHASH-THRESHOLD
                 :WARN-IF-NEEDS-REHASH-AFTER-GC :WEAK)
</programlisting>

<para>The &test-k; argument can be, other than one of the symbols &eq;,
 &eql;, &equal;, &equalp;, one of the symbols &fasthash-eq; and
 &stablehash-eq;.  Both of these tests use &eq; as the comparison
 function; they differ in their performance characteristics.
 <variablelist>
  <varlistentry><term>&fasthash-eq;</term>
   <listitem><simpara>This uses the fastest possible hash function.
     Its drawback is that its hash codes become invalid at every &gc;ion
     (except if all keys are &immediate-o;s),
     thus requiring a reorganization of the hash table at the first
     access after each &gc;ion. Especially when generational &gc;ion is used,
     which leads to frequent small &gc;ions, large hash table with this test
     can lead to scalability problems.</simpara></listitem></varlistentry>
  <varlistentry><term>&stablehash-eq;</term>
   <listitem><simpara>This uses a slower hash function that has the
     property that its hash codes for instances of the classes &symbol-t;,
     &standard-stablehash; (subclass of &standard-object-t;) and
     &structure-stablehash; (subclass of &structure-object-t;) are
     stable across GCs.
     This test can thus avoid the scalability problems if all keys,
     other than &immediate-o;s, are &symbol-t;, &standard-stablehash; or
     &structure-stablehash; instances.</simpara></listitem></varlistentry>
 </variablelist>
 One can recommend to use &fasthash-eq; for short-lived hash tables.
 For tables with a longer lifespan which can be big or accessed
 frequently, it is recommended to use &stablehash-eq;, and to modify the
 objects that are used as its keys to become instances of
 &standard-stablehash; or &structure-stablehash;.
</para>

<para>When the symbol &eq; or the function <literal>#'eq</literal> is
used as a &test-k; argument, the value of the variable
 <firstterm><varname>CUSTOM:*EQ-HASHFUNCTION*</varname>
  <indexterm id="eq-hashfunction" significance="preferred">
   <primary>*EQ-HASHFUNCTION*</primary></indexterm></firstterm> is used instead.
This value must be one of &fasthash-eq;, &stablehash-eq;.</para>

<para>Similarly, the &test-k; argument can also be one
 of the symbols <constant>EXT:FASTHASH-EQL</constant>,
 <constant>EXT:STABLEHASH-EQL</constant>,
 <constant>EXT:FASTHASH-EQUAL</constant>,
 <constant>EXT:STABLEHASH-EQUAL</constant>.
 The same remarks apply as for &fasthash-eq; and &stablehash-eq;.
 When the symbol &eql; or the function <literal>#'eql</literal> is used
 as a &test-k; argument, the value of the variable
 <firstterm><varname>CUSTOM:*EQL-HASHFUNCTION*</varname>
  <indexterm id="eql-hashfunction" significance="preferred">
   <primary>*EQL-HASHFUNCTION*</primary></indexterm></firstterm> is used
 instead; this value must be one of <constant>EXT:FASTHASH-EQL</constant>,
 <constant>EXT:STABLEHASH-EQL</constant>.
 Similarly, when the symbol &equal; or the function <literal>#'equal</literal>
 is used as a &test-k; argument, the value of the variable
 <firstterm><varname>CUSTOM:*EQUAL-HASHFUNCTION*</varname>
  <indexterm id="equal-hashfunction" significance="preferred">
   <primary>*EQUAL-HASHFUNCTION*</primary></indexterm></firstterm> is used
 instead; this value must be one of <constant>EXT:FASTHASH-EQUAL</constant>,
 <constant>EXT:STABLEHASH-EQUAL</constant>.</para>

<para>The <constant>:WARN-IF-NEEDS-REHASH-AFTER-GC</constant> argument,
if true, causes a &warning-t; to be &signal;ed when an object is stored
into the table which will force table reorganizations at the first
access of the table after each &gc;ion.
This keyword argument can be used to check whether &stablehash-eq;
should be preferred over &fasthash-eq; for a particular table.
Use <function>HASH-TABLE-WARN-IF-NEEDS-REHASH-AFTER-GC</function>
to check and &setf; this parameter after the table has been created.</para>

<para>The <constant>:INITIAL-CONTENTS</constant> argument is an
 &alist; that is used to initialize the new hash table.</para>

<para>The <constant>:REHASH-THRESHOLD</constant> argument is ignored.</para>

<para>The <constant>:WEAK</constant> argument can take the following values:
 <simplelist columns="1">
 <member>&nil; (default)</member>
 <member>&key-k;</member>
 <member>&value-k;</member>
 <member>&key-and-value-k;</member>
 <member>&key-or-value-k;</member>
</simplelist>
and specifies whether the &hash-table-t; is <emphasis>weak</emphasis>:
if the key, value, either or both are not accessible for the &gc;ion
purposes, i.e., if they are only accessible via weak &hash-table-t;s
and &weak-pointer;s, it is &gc;ed and removed from the weak
&hash-table-t;.</para>

<para>The &setf;able predicate <function>EXT:HASH-TABLE-WEAK-P</function>
checks whether the &hash-table-t; is weak.</para>

<para>Note that the only test that makes sense for weak hash tables are
&eq; and its variants &fasthash-eq; and &stablehash-eq;.</para>

<para>Just like all other <link linkend="weak">weak objects</link>, weak
&hash-table-t;s cannot be printed readably.</para>

<para>See also <xref linkend="weak-ht"/>.</para>

<section id="hashtable-gc-rehash">
 <title>Interaction between &hash-table-t;s and &gc;ion</title>

<para>When a hash table contains keys to be compared by identity - such
 as &number-t;s in &hash-table-t;s with the &hash-table-test; &eq;;
 or &cons-t;es in tables which test with &eq; or &eql;;
 or &vector-t;s in tables which test with &eq;, &eql; or &equal;;
 or &standard-object-t; or &structure-object-t; instances in tables which
 test with &eq;, &eql;, &equal; or &equalp;;
 - the hash code will in general depend on the object's address in
 memory.  Therefore it will in general be invalidated after a &gc;ion,
 and the hash table's internal structure must be recomputed at the next
 table access.</para>

<para>While <constant>:WARN-IF-NEEDS-REHASH-AFTER-GC</constant> can help
 checking the efficiency of a particular &hash-table-t;, the variable
<firstterm>&warn-on-hashtable-needing-rehash-after-gc;
 <indexterm id="hashtable-gc-rehash-warn" significance="preferred">
  <primary>*WARN-ON-HASHTABLE-NEEDING-REHASH-AFTER-GC*</primary>
</indexterm></firstterm>
 achieves the same effect for all &hash-table-t;s in the system at once:
 when &warn-on-hashtable-needing-rehash-after-gc; is true and a
 &hash-table-t; needs to be rehashed after a &gc;ion, a warning is
 issued that shows the inefficient &hash-table-t;.</para>

<para>What can be done to avoid the inefficiencies detected by these warnings?
 <orderedlist><listitem><simpara>In many cases you can solve the problem
    by using the <function>STABLEHASH</function> variant of the hash
    test.</simpara></listitem>
  <listitem><simpara>In other cases, namely &standard-object-t; or
    &structure-object-t; instances, you can solve the problem by making
    the key object classes inherit from &standard-stablehash; or
    &structure-stablehash;, respectively.</simpara></listitem>
  <listitem><simpara>In the remaining cases, you should store a hash key
    inside the object, of which you can guarantee uniqueness through
    your application (for example the ID of an object in a database, or
    the serial number of an object), and use this key as hash key
    instead of the original object.</simpara></listitem></orderedlist></para>
</section>

</section>

<section id="defhash"><title>Macro &defhash;</title>

<para>You can define a new hash table test using the macro
 &defhash;: <code>(&defhash; test-name &test-f; &hash-f;)</code>, after
 which &name-r; can be passed as the &test-k; argument to &make-hash-table;.
 E.g.: <programlisting language="lisp">(&defhash; string &string-eq; &sxhash;)
<computeroutput>STRING</computeroutput>
(&make-hash-table; :test 'string)
<computeroutput>#S(HASH-TABLE :TEST (#&lt;SYSTEM-FUNCTION STRING=&gt; . #&lt;SYSTEM-FUNCTION SXHASH&gt;))</computeroutput></programlisting>
(which is not too useful because it is equivalent to an &equal;
&hash-table-t; but less efficient).</para>

<para>The fundamental requirement is that the &test-f; and &hash-f; are
 consistent: <programlisting language="lisp">
(&funcall; &test-f; &x-r; &y-r;) &rArr;
(&areq; (&funcall; &hash-f; &x-r;) (&funcall; &hash-f; &y-r;))</programlisting>
 This means that the following definition: <programlisting language="lisp">
(&defhash; number &areq; &sxhash;)<lineannotation>broken!</lineannotation></programlisting>
 is &not-e; correct because <programlisting language="lisp">
(&areq; 1 1d0)
<computeroutput>&t;</computeroutput><lineannotation>same object!</lineannotation>
(&areq; (&sxhash; 1) (&sxhash; 1d0))
<computeroutput>&nil;</computeroutput><lineannotation>different buckets!</lineannotation></programlisting>
 The correct way is, e.g.: <programlisting language="lisp">
(&defhash; number &areq; (&lambda-m; (x) (&sxhash; (&coerce; x '&short-float-t;))))</programlisting></para>
<note><simpara>Note that &coerce;ing to a &short-float-t; does &not-e; cons up
  &fresh; objects while &coerce;ing to a &double-float-t; does.</simpara></note>

</section>

<section id="ht-test"><title>Function &hash-table-test;</title>
<para>Function &hash-table-test; returns either one of
 <simplelist columns="2"><member>&fasthash-eq;</member>
  <member>&stablehash-eq;</member>
  <member><constant>EXT:FASTHASH-EQL</constant></member>
  <member><constant>EXT:STABLEHASH-EQL</constant></member>
  <member><constant>EXT:FASTHASH-EQUAL</constant></member>
  <member><constant>EXT:STABLEHASH-EQUAL</constant></member>
  <member>&equalp;</member></simplelist>
 (but &not-e; &eq;, &eql; nor &equal; anymore), or, for &hash-table-t;s
 created with a user-defined &hash-table-test; (see macro &defhash;),
 a &cons-t; cell <returnvalue>(&test-f; . &hash-f;)</returnvalue>.
</para></section>

<section id="dohash"><title>Macro &dohash;</title>

<para>For iteration through a &hash-table-t;, a macro &dohash;,
 similar to &dolist;, can be used instead of &maphash;:</para>

<programlisting language="lisp">
(&dohash; (<replaceable>key-var</replaceable> <replaceable>value-var</replaceable> <replaceable>hash-table-form</replaceable> [<replaceable>resultform</replaceable>])
  {&declaration-r;}*
  {&tag-r;|&form-r;}*)
</programlisting>

<para>&dohash; forms are &iter-form;s.</para>

</section>
</chapter>

<chapter id="filenames"><title>Filenames
  <ulink role="clhs" url="chap-19"/></title>

<para>For most operations, pathnames denoting files and pathnames
 denoting directories cannot be used interchangeably.</para>

<variablelist>
<!-- #if defined(PATHNAME_UNIX) -->
<varlistentry><term>&unix-only;</term>
<listitem><simpara>For example, <filename>#P"foo/bar"</filename> denotes
 the file &bar-f; in the directory &foo-f;,
 while <filename>#P"foo/bar/"</filename> denotes the subdirectory
 &bar-f; of the directory &foo-f;.
</simpara></listitem></varlistentry>
<!-- #endif -->

<!-- #ifdef PATHNAME_WIN32 -->
<varlistentry><term>&win32-only;</term>
<listitem><simpara>For example, <filename>#P"foo\\bar"</filename>
 denotes the file &bar-f; in the directory &foo-f;,
 while <filename>#P"foo\\bar\\"</filename> denotes the subdirectory
 &bar-f; of the directory &foo-f;.
</simpara></listitem></varlistentry>
<!-- #endif -->

<!-- #if defined(PATHNAME_WIN32) || defined(UNIX_CYGWIN32) -->
<varlistentry id="device-prefix"><term>&win32-cygwin-only;</term>
 <listitem><simpara>User variable <firstterm>&dev-prefix;</firstterm>
  controls translation between &cygwin; pathnames
  (e.g., <filename>#P"/cygdrive/c/gnu/clisp/"</filename>) and native
  &win32; pathnames (e.g., <filename>#P"C:\\gnu\\clisp\\"</filename>)
  When it is set to &nil;, no translations occur and the &cygwin; port
  will not understand the native paths and the native &win32; port will
  not understand the &cygwin; paths.
  When its value is a string, it is used by &parse-namestring; to
  translate into the appropriate platform-specific representation,
  so that on &cygwin;, <code>(&parse-namestring; "c:/gnu/clisp/")</code>
  returns <filename>#P"/cygdrive/c/gnu/clisp/"</filename>,
  while on &win32; <code>(&parse-namestring; "/cygdrive/c/gnu/clisp/")</code>
  returns <filename>#P"C:/gnu/clisp/"</filename>.
  The initial value is <literal>"cygdrive"</literal>, you should edit
  &config-lisp; to change it.</simpara></listitem></varlistentry>
<!-- #endif -->
</variablelist>

<para>This is especially important for the
 <link linkend="dir">directory-handling functions</link>.</para>

<table id="min-filename-syntax-table" frame="all">
  <title>The minimum filename syntax that may be used portably</title>
 <tgroup cols="2" colsep="1" rowsep="1" align="left">
 <thead><row><entry>pathname</entry><entry>meaning</entry></row></thead><tbody>
 <row><entry><filename>"xxx"</filename></entry>
   <entry>for a file with name <replaceable>xxx</replaceable></entry></row>
 <row><entry><filename>"xxx.yy"</filename></entry>
   <entry>for a file with name <replaceable>xxx</replaceable> and type
   <replaceable>yy</replaceable></entry></row>
 <row><entry><filename>".yy"</filename></entry>
   <entry>for a pathname with type <replaceable>yy</replaceable> and no
    name or with name <replaceable>.yy</replaceable> and no type,
    depending on the value of &parsedot;.</entry></row>
</tbody></tgroup></table>

<para>Hereby <replaceable>xxx</replaceable> denotes 1 to 8 characters,
 and <replaceable>yy</replaceable> denotes 1 to 3 characters, each of
 which being either an alphanumeric character or the underscore
 <keysym>#\_</keysym>.  Other properties of pathname syntax vary between
 operating systems.</para>

<section id="path-components"><title>Pathname Components
  <ulink role="clhs" url="sec_19-2-1"/></title>

<para>When a pathname is to be fully specified (no wildcards), that
 means that no &wild-k;, &wild-inferiors-k; is allowed, no wildcard
 characters are allowed in the strings, and &name-r; &eq; &nil; may not
 be allowed either.</para>

<section id="path-dir-canon"><title>Directory canonicalization</title>
<para>As permitted by the &make-pathname; specification, the &pathname-t;
 directory component is canonicalized when the pathname is constructed:
 <orderedlist>
  <listitem><simpara><filename>""</filename> and
    <filename>"."</filename> are removed</simpara></listitem>
  <listitem><simpara><filename>".."</filename>,
    <filename>"*"</filename>, and <filename>"**"</filename> are converted
    to <constant>:UP</constant>, &wild-k; and &wild-inferiors-k;,
    respectively</simpara></listitem>
  <listitem><simpara>patterns <filename>foo/../</filename> are
    collapsed</simpara></listitem>
 </orderedlist>
</para>
</section>

<section id="path-platform-specific"><title>Platform-specific issues</title>

<!-- #ifdef PATHNAME_UNIX -->
<variablelist>
<varlistentry><term>&unix-only;</term>
<listitem><variablelist>&path-comps;
<varlistentry><term>&host-r;</term>&always-nil;</varlistentry>
<varlistentry><term>&device-r;</term>&always-nil;</varlistentry>
&unix-win32-dir-name-type-version;
</variablelist>

<para>A &unix; &name-type-split;</para>

<informaltable id="unix-filename-table" frame="all">
 <tgroup cols="2" colsep="1" rowsep="1" align="center"><tbody>
 <row><entry>External notation:</entry><entry>
  <filename>"server:sub1.typ/sub2.typ/name.typ"</filename></entry></row>
 <row><entry>using defaults:</entry><entry>
  <filename>       "sub1.typ/sub2.typ/name.typ"</filename></entry></row>
 <row><entry>or</entry><entry>
  <filename>                         "name.typ"</filename></entry></row>
 <row><entry>or</entry><entry>
  <filename>       "sub1.typ/**/sub3.typ/x*.lisp"</filename></entry></row>
 <row><entry>or similar.</entry><entry/></row>
</tbody></tgroup></informaltable>
</listitem></varlistentry></variablelist>
<!-- #endif -->

<!-- #if defined(PATHNAME_WIN32) -->
<variablelist>
<varlistentry><term>&win32-only;</term>
<listitem><variablelist>&path-comps;
<varlistentry><term>&host-r;</term>
 <listitem><simpara>&nil; or &simple-string-t;, wildcard characters may
   occur but do not act as wildcards</simpara></listitem></varlistentry>
<varlistentry><term>&device-r;</term>
 <listitem><simpara>&nil; or &wild-k; or &file-letter-uc;
 </simpara></listitem></varlistentry>
&unix-win32-dir-name-type-version;
</variablelist>

<para>If &host-r; is non-&nil;, &device-r; must be &nil;.</para>

<para>A &win32; &name-type-split;</para>

<informaltable id="win32-filename-table" frame="all">
 <tgroup cols="2" colsep="1" rowsep="1" align="center"><tbody>
 <row><entry>External notation:</entry>
  <entry><filename>"A:\sub1.typ\sub2.typ\name.typ"</filename></entry></row>
 <row><entry>using defaults:</entry>
  <entry><filename>  "\sub1.typ\sub2.typ\name.typ"</filename></entry></row>
 <row><entry>or</entry>
  <entry><filename>                     "name.typ"</filename></entry></row>
 <row><entry>or</entry>
  <entry><filename>"*:\sub1.typ\**\sub3.typ\x*.lisp"</filename></entry></row>
 <row><entry>or similar.</entry><entry/></row>
</tbody></tgroup></informaltable>

<para>Instead of &file-bsla; one may use &file-slash;, as usual for DOS
 calls.</para>

<para>If &host-r; is non-&nil; and the &dir-r;'s &startpoint-r;
 is not &absolute-k;, <code>(&parse-namestring; (&namestring;
 &path-r;))</code> will not be the same as &path-r;.</para>

</listitem></varlistentry></variablelist>
<!-- #endif -->

<!-- #ifdef PATHNAME_NOEXT -->
<variablelist>
<varlistentry><term>&unix-w32-only;</term>
<listitem><simpara>The wildcard characters: &file-star; matches any
 sequence of characters, &file-ques; matches any one character.
 </simpara></listitem></varlistentry>
</variablelist>
<!-- #endif -->

<!-- #ifdef PATHNAME_NOEXT -->
<formalpara id="name-type-split"><title>Name/type namestring split</title>
<para><variablelist>
<varlistentry><term>&unix-w32-only;</term>
<listitem><para>A filename is split into name and type according to the
 following rule: <itemizedlist>
  <listitem><simpara>if there is no &file-dot; in the filename, then the
   &name-r; is everything, &type-r; is &nil;;</simpara></listitem>
  <listitem><simpara>if there is a &file-dot;, then &name-r; is the part
   before and &type-r; the part after the last dot.</simpara></listitem>
  <listitem><para>if the only &file-dot; is the first character, then
   the behavior depends on the value of the user variable
    <firstterm>&parsedot;</firstterm>
   which can be either
   <variablelist><varlistentry><term>&type-k;</term>
    <listitem><simpara>&nil; &name-r;, everything after the &file-dot;
     is the &type-r;; or</simpara></listitem></varlistentry>
   <varlistentry><term>&name-k;</term>
    <listitem><simpara>&nil; &type-r;, everything is the
     &name-r;</simpara></listitem></varlistentry></variablelist>
   </para></listitem>
  </itemizedlist></para>
 <note><simpara>Due to this name/type splitting rule, there are pathnames
   that cannot result from &parse-namestring;.
   To get a pathname whose type contains a dot or whose name contains a
   dot and whose type is &nil;, &make-pathname; must be used.  Example:
   <code>(&make-pathname; &name-k; "foo.bar")</code>.</simpara></note>
</listitem></varlistentry></variablelist></para></formalpara>
<!-- #endif -->
</section>

</section>

<section id="unspecific"><title>:UNSPECIFIC as a Component Value
 <ulink role="clhs" url="sec_19-2-2-2-3"/></title>

<para>The symbol <constant>:UNSPECIFIC</constant> is not permitted as a
 pathname component for any slot of any pathname.
 It is also illegal to pass it as an argument to &make-pathname;,
 although it &is-e; a legal argument (treated as &nil;)
 to &user-homedir-pathname;.</para>

<para>The only use for <constant>:UNSPECIFIC</constant> is that it is
 returned by &pathname-device; for &logical-pathname-t;s, as required by
 <ulink role="clhs" url="sec_19-3-2-1"/>.</para>
</section>

<section id="path-external-notation"><title>External notation</title>

<para>External notation of pathnames (cf. &parse-namestring; and
 &namestring;), of course without spaces, [,],{,}:</para>

<variablelist>
<!-- #ifdef PATHNAME_UNIX -->
<varlistentry><term>&unix-only;</term>
<listitem><informaltable id="unix-path-external-table" frame="all">
 <tgroup cols="2" colsep="1" rowsep="1" align="center"><tbody>
  <row><entry>[ &file-slash; ]</entry>
   <entry>&file-slash; denotes absolute pathnames</entry></row>
  <row><entry>{ &name-r; &file-slash; }</entry>
   <entry>each &name-r; is a subdirectory</entry></row>
  <row><entry>[ &name-r; [&file-dot; &type-r;] ]</entry>
   <entry>filename with type (extension)</entry></row>
</tbody></tgroup></informaltable>

<para>Name and type may be &string-t;s of any &length;
 (consisting of &printing; &character-t;s, except &file-slash;).</para>
</listitem></varlistentry>
<!-- #endif -->

<!-- #ifdef PATHNAME_WIN32 -->
<varlistentry><term>&win32-only;</term>
<listitem><informaltable id="win32-path-external-table" frame="all">
 <tgroup cols="2" colsep="1" rowsep="1" align="center"><tbody>
  <row><entry>[ [<replaceable>drivespec</replaceable>] : ]</entry>
   <entry>a letter &file-star;|&file-letter-lc;|&file-letter-uc;</entry></row>
  <row><entry>{ &name-r; [. &type-r;] \ }</entry>
   <entry>each &name-r; is a subdirectory, &file-bsla; may be
     replaced by &file-slash;</entry></row>
  <row><entry>[ &name-r; [. &type-r;] ]</entry>
   <entry>filename with type (extension)</entry></row>
</tbody></tgroup></informaltable>

<para>Name and type may be &string-t;s of any &length;
 (consisting of &printing; &character-t;s, except &file-slash;,
 &file-bsla;, &file-colon;).</para></listitem></varlistentry>
<!-- #endif -->

</variablelist>

</section>

<section id="log-path"><title>Logical Pathnames
  <ulink role="clhs" url="sec_19-3"/></title>
 <para>No notes.</para>
</section>

<section id="filename-misc"><title>Miscellaneous</title>

<formalpara id="path-des"><title>Pathname Designators</title>
 <para>When &parsename; is &nil;, &symbol-t; is also treated as a
  <ulink url="clhs/glo">pathname designator</ulink>,
  namely its &symbol-name; is converted to the
  operating system's preferred pathname case.</para></formalpara>

<formalpara id="path-match"><title>Function &pathname-match-p;</title>
 <para>&pathname-match-p; does not interpret missing components as
  wild.</para></formalpara>

<section id="translate-pathname"><title>Function &translate-pathname;</title>

<para>&translate-pathname; accepts three additional keyword arguments:
 <code>(&translate-pathname; &source-r;
 <replaceable>from-wildname</replaceable>
 <replaceable>to-wildname</replaceable> &key-amp; &all-k;
 &merge-k; &absolute-k;)</code></para>

<para>If &all-k; is specified and non-&nil;, a list of all resulting
 pathnames, corresponding to all matches of <code>(&pathname-match-p;
  &source-r; <replaceable>from-wildname</replaceable>)</code>, is
 returned.</para>

<para>If &merge-k; is specified and &nil;, unspecified pieces of
 <replaceable>to-pathname</replaceable> are not replaced by
 corresponding pieces of &source-r;.</para>

<para>If &absolute-k; is specified and non-&nil;, the returned
 pathnames are converted to absolute by merging in the current process'
 directory, therefore rendering pathnames suitable for the OS and
 external programs.  So, to pass a pathname to an external program, you
 do <code>(&namestring; (&translate-pathname; &path-r;
 #P"" #P"" &absolute-k; &t;))</code> or <code>(&namestring;
 (&absolute-pathname; &path-r;))</code>.</para>

</section>

<section id="translate-logpath">
 <title>Function &translate-logical-pathname;</title>

<para>&translate-logical-pathname; accepts an additional keyword
 argument &absolute-k;, similar to <xref linkend="translate-pathname"/>.</para>

</section>

<section id="parsename"><title>Function &parse-namestring;</title>

<para><code>(&parse-namestring; &string-r; &optional-amp;
   &host-r; &defaults-r; &key-amp; &start-r; &end-r;
   <replaceable>junk-allowed</replaceable>)</code>
 returns a logical pathname only if &host-r; is a
 <ulink url="clhs/glo">logical host</ulink>
 or &host-r; is &nil; and &defaults-r; is a &logical-pathname-t;.
 To construct a logical pathname from a string, the function
 &logical-pathname; can be used.</para>

<para>The &ansi-cl; behavior of recognizing logical pathnames when
 the &string-r; begins with some alphanumeric characters followed by a
 colon (<keysym>#\:</keysym>) can be very confusing
 (cf. <filename>"c:/autoexec.bat"</filename>,
 <filename>"home:.clisprc"</filename> and
 <filename>"prep:/pub/gnu"</filename>)
 and therefore is disabled by default.
 To enable the &ansi-cl; behavior, you should set &parsename; to non-&nil;.
 Note that this also disables treating &symbol-t;s as &path-des;s.</para>
</section>

<section id="pathmerge"><title>Function &merge-pathnames;</title>

<para><code>(&merge-pathnames; &path-r;
   [<replaceable>default-pathname</replaceable>])</code> returns a
   logical pathname only if
 <replaceable>default-pathname</replaceable> is a &logical-pathname-t;.
 To construct a logical pathname from a &string-t;, the function
 &logical-pathname; can be used.</para>

<para>When both &path-r; and <replaceable>default-pathname</replaceable>
 are relative pathnames, the behavior depends on &pathmerge;: when it is
 &nil;, then &clisp; retains its traditional behavior:
 <code>(&merge-pathnames; #P"x/" #P"y/")</code>
 evaluates to <filename>#P"x/"</filename></para>

<formalpara><title>Rationale</title>
<para>&merge-pathnames; is used to specify default components for
 pathnames, so there is some analogy between
 <code>(&merge-pathnames; a b)</code> and
 <code>(&or-m; a b)</code>.  Obviously, putting in the
 same default a second time should do the same as putting it in once:
 <code>(&or-m; a b b)</code> is the same as <code>(&or-m; a b)</code>, so
 <code>(&merge-pathnames; (&merge-pathnames; a b) b)</code>
 should be the same as <code>(&merge-pathnames; a b)</code>.
</para></formalpara>

<para>(This question actually does matter because in &cl; there is no
 distinction between <quote>pathnames with defaults merged-in</quote> and
 <quote>pathnames with defaults not yet applied</quote>.)</para>

<para>Now, <code>(&merge-pathnames; (&merge-pathnames; #P"x/" #P"y/")
  #P"y/")</code> and <code>(&merge-pathnames; #P"x/" #P"y/")</code> are
 &equal; in &clisp; (when &pathmerge; is &nil;), but not in
 implementations that strictly follow the &ansi-cl;.
 In fact, the above <emphasis>twice-default = once-default</emphasis>
 rule holds for all pathnames in &clisp;.</para>

<para>Conversely, when &pathmerge; is non-&nil;, the normal &ansi-cl;
 behavior is exhibited: <code>(&merge-pathnames; #P"x/" #P"y/")</code>
 evaluates to <filename>#P"y/x/"</filename>.</para>

<formalpara><title>Rationale</title>
<para><quote>merge</quote> is <emphasis>merge</emphasis> and
 not <emphasis>or</emphasis>.</para></formalpara>
</section>

<section id="load-lpt">
 <title>Function &load-logical-pathname-translations;</title>

<para>When the &host-r; argument to &load-logical-pathname-translations;
is not a defined logical host yet, we proceed as follows:
<orderedlist numeration="arabic">
 <listitem><simpara>If both &env-var;s
  <envar>LOGICAL_HOST_&host-r;_FROM</envar> and
  <envar>LOGICAL_HOST_&host-r;_TO</envar> exist, then their values
  define the map of the &host-r;.</simpara></listitem>
 <listitem><simpara>If the &env-var;
  <envar>LOGICAL_HOST_&host-r;</envar> exists, its value is read from,
  and the result is passed to <code>(&setf;
  &logical-pathname-translations;)</code>.</simpara></listitem>
 <listitem><simpara>Variable &load-lpt-db; is consulted.
  Its value should be a &list-t; of files and/or directories,
  which are searched for in the &load-paths;, just like for &load-my;.
  When the element is a file, it is repeatedly &read; from,
  <ulink url="http://www.franz.com/support/documentation/6.0/doc/pathnames.htm#load-logical-pathname-translations-2">Allegro CL-style</ulink>,
  odd objects being host names and even object being their
  &logical-pathname-translations;.
  When the element is a directory, a file, named <filename>&host-r;</filename>
  or <filename>&host-r;.host</filename>, in that directory, is &read;
from once, <ulink url="http://common-lisp.net/project/cmucl/doc/cmu-user/extensions.html#logical-pathnames">CMUCL-style</ulink>,
  the object read being the &logical-pathname-translations; of the
  &host-r;.</simpara></listitem></orderedlist></para>
</section>

<section id="absolute-pathname"><title>Function &absolute-pathname;</title>
 <para><code>(&absolute-pathname; &path-r;)</code> converts the &path-r;
 to a physical pathname, then - if its directory component is not
 absolute - converts it to an absolute pathname, by merging in the
 current process' directory. This is like &truename;, except that it
 does not verify that a file named by the &path-r; exists, not even that
 its directory exists. It does no filesystem accesses, except to
 determine the current directory. This function is useful when you want
 to save a pathname over time, or pass a pathname to an external
 program.</para></section>

</section>
</chapter>


<chapter id="files"><title>Files <ulink role="clhs" url="chap-20"/></title>

<section id="dir-is-not-file"><title>Directory is &not-e; a file</title>
<para>&clisp; has traditionally taken the view that a directory is a
 separate object and &not-e; a special kind of file, so whenever the
 standard says that a function operates on <emphasis>files</emphasis>
 without specifically mentioning that it also works on
 <emphasis>directories</emphasis>, &clisp; &sig-err; when passed a
 directory.</para>
<para>&clisp; provides separate directory functions, such as
 &delete-dir;, &rename-dir; et al.</para>
<para>You can use &directory; or &probe-path; to figure out whether a
 given namestring refers to a file or a directory.</para>

<section id="probe-path"><title>Function &probe-path;</title>
<para>Function &probe-path; figures out whether the argument refers to
 an existing directory or an existing regular file, and returns 4 values
 if the filesystem object exists: <orderedlist>
  <listitem><simpara>&truename;</simpara></listitem>
  <listitem><simpara>&absolute-pathname;</simpara></listitem>
  <listitem><simpara>&file-write-date;</simpara></listitem>
  <listitem><simpara>&file-size;</simpara></listitem>
 </orderedlist> or &nil; if it does not exist.
 E.g., if you have a file &file-r;, a directory &dir-r;,
 a symbolic link <filename>link-file</filename> pointing to &file-r;
 and a symbolic link <filename>link-dir</filename> pointing to &dir-r;,
 then<programlisting language="lisp">
(&probe-path; #P"filename")
<computeroutput>#P"/.../filename"</computeroutput>
<computeroutput>#P"/.../filename"</computeroutput>
<computeroutput>3427467015</computeroutput>
<computeroutput>3171976</computeroutput>
(&probe-path; #P"filename/")
<computeroutput>#P"/.../filename"</computeroutput>
<computeroutput>#P"/.../filename"</computeroutput>
<computeroutput>3427467015</computeroutput>
<computeroutput>3171976</computeroutput>
(&probe-path; #P"directory")
<computeroutput>#P"/.../directory/"</computeroutput>
<computeroutput>#P"/.../directory/"</computeroutput>
<computeroutput>3426940352</computeroutput>
<computeroutput>1024</computeroutput>
(&probe-path; #P"directory/")
<computeroutput>#P"/.../directory/"</computeroutput>
<computeroutput>#P"/.../directory/"</computeroutput>
<computeroutput>3426940352</computeroutput>
<computeroutput>1024</computeroutput>
(&probe-path; #P"link-file")
<computeroutput>#P"/.../filename"</computeroutput>
<computeroutput>#P"/.../link-file"</computeroutput>
<computeroutput>3427467015</computeroutput>
<computeroutput>3171976</computeroutput>
(&probe-path; #P"link-file/")
<computeroutput>#P"/.../filename"</computeroutput>
<computeroutput>#P"/.../link-file"</computeroutput>
<computeroutput>3427467015</computeroutput>
<computeroutput>3171976</computeroutput>
(&probe-path; #P"link-dir")
<computeroutput>#P"/.../directory/"</computeroutput>
<computeroutput>#P"/.../link-dir/"</computeroutput>
<computeroutput>3426940352</computeroutput>
<computeroutput>1024</computeroutput>
(&probe-path; #P"link-dir/")
<computeroutput>#P"/.../directory/"</computeroutput>
<computeroutput>#P"/.../link-dir/"</computeroutput>
<computeroutput>3426940352</computeroutput>
<computeroutput>1024</computeroutput>
</programlisting></para>
<para>This function may also &sig-err; if, e.g., its argument resides
under a tree for which you do not have sufficient access privileges.</para>
</section></section>

<section id="file-func"><title>File functions</title>

<section id="probe-file"><title>Function &probe-file;</title>
<para>&probe-file; cannot be used to check whether a directory exists.
 Use functions &probe-dir;, &probe-path; or &directory; for this.
</para></section>

<section id="file-author"><title>Function &file-author;</title>
<para>&file-author; always returns &nil;, because the operating systems
 &clisp; is ported to do not store a file's author in the file system.
 Some operating systems, such as &unix;, have the notion of a file's
 <emphasis>owner</emphasis>, and some other &cl; implementations return
 the user name of the file owner.  &clisp; does not do this, because
 <emphasis>owner</emphasis> and <emphasis>author</emphasis> are not the
 same; in particular, authorship is preserved by copying, while
 ownership is not.</para>
<para>Use <link linkend="file-owner"><function>OS:FILE-OWNER</function></link>
 to find the owner of the file.  See also
 <link linkend="file-properties"><function>OS:FILE-PROPERTIES</function></link>
 (&win32-only;).</para></section>

<section id="del-file"><title>Function &delete-file;</title>
<para><code>(&delete-file; &path-r;)</code> deletes the pathname
 &path-r;, not its &truename;, and returns the absolute pathname it
 actually removed or &nil; if &path-r; did not exist.
 When &path-r; points to a file which is currently open in &clisp;,
 an &err-sig;.
 To remove a directory, use &delete-dir; instead.</para></section>

<section id="rename-file"><title>Function &rename-file;</title>
<para>This functions accepts and extra keyword argument &if-exists;.
 When it is &error-k; (the default), an &err-sig; if the destination
 pathname names an existing file, otherwise (e.g., if it is &overwrite-k;)
 the destination file atomically overwritten.</para>
<para>When &ansi; is non-&nil;, only the standard two arguments are accepted,
 and and &err-sig; when the destination pathname names an existing file.</para>
<para>This function cannot operate on directories,
 use &rename-dir; to rename a directory.</para></section>

</section>

<section id="dir-func"><title>Directory functions</title>

<section id="probe-dir"><title>Function &probe-dir;</title>
<para><code>(&probe-dir; &path-r;)</code> tests whether &path-r; exists
 and is a directory.
 It will, unlike &probe-file; or &truename;, not &signal; an &error-t;
 if the parent directory of &path-r; does not exist.</para></section>

<section id="directory"><title>Function &directory;</title>

<para><code>(&directory; &optional-amp; &path-r; &key-amp;
  :FULL :CIRCLE &if-does-not-exist;)</code> can run in two modes:
<itemizedlist>
 <listitem><simpara>If &path-r; contains no name or type component, a
  list of all matching directories is produced.
  E.g., <code>(&directory; "/etc/*/")</code> lists
  all subdirectories in the directory
  <filename>#P"/etc/"</filename>.</simpara></listitem>
 <listitem><simpara>Otherwise a list of all matching files is returned.
  E.g., <code>(&directory; "/etc/*")</code> lists all
  regular files in the directory <filename>#P"/etc/"</filename>.
</simpara></listitem></itemizedlist>

If you want &all-e; the files &and-e; subdirectories in the current directory,
 you should use <code>(&nconc; (&directory; "*/") (&directory; "*"))</code>.
If you want all the files and subdirectories in all the subdirectories
under the current directory (similar to the <command role="unix">ls
 <option>-R</option></command> &unix; command), use
<code>(&nconc; (&directory; "**/") (&directory; "**/*"))</code>.</para>

<variablelist><title>Keyword arguments accepted by &directory;</title>
<varlistentry><term><constant>:FULL</constant></term>
 <listitem><simpara>If this argument is non-&nil;, additional
  information is returned: for each matching file you get a &list-t; of
  at least four elements <returnvalue>(<replaceable>file-pathname</replaceable>
    <replaceable>file-truename</replaceable>
    <replaceable>file-write-date-as-decoded-time</replaceable>
    <replaceable>file-length</replaceable>)</returnvalue>.
</simpara></listitem></varlistentry>
<varlistentry><term><constant>:CIRCLE</constant></term>
<listitem><simpara>If this argument is non-&nil;, &directory; avoids
 endless loops that may result from symbolic links.
</simpara></listitem></varlistentry>
<varlistentry><term>&if-does-not-exist;</term>
<listitem><para>This argument controls the treatment of links
  pointing to non-existent files and can take the following values:
  <variablelist>
   <varlistentry><term><constant>:DISCARD</constant> (default)</term>
    <listitem><simpara>discard the bad directory entries
   </simpara></listitem></varlistentry>
   <varlistentry><term>&error-k;</term>
    <listitem><simpara>an &err-sig; on bad directory entries
      (this corresponds to the default behavior of &directory; in &cmucl;)
   </simpara></listitem></varlistentry>
   <varlistentry><term><constant>:KEEP</constant></term>
    <listitem><simpara>keep bad directory entries in the returned list
      (this roughly corresponds to the <code>(&directory;
       ... <constant>:TRUNAMEP</constant> &nil;)</code> call in &cmucl;)
   </simpara></listitem></varlistentry>
   <varlistentry><term>&ignore-k;</term>
    <listitem><simpara>Similar to <constant>:DISCARD</constant>, but also do
      &not-e; &signal; an &error-t; when a directory is unaccessible (contrary
      to the &ansi-cl; specification).</simpara></listitem></varlistentry>
</variablelist></para></listitem></varlistentry></variablelist>
</section>

<section id="dir"><title>Function <function>EXT:DIR</function></title>
<para><code>(<function>EXT:DIR</function> &optional-amp;
 &path-r;)</code> is like &directory;, but displays the pathnames
 instead of returning them. <code>(EXT:DIR)</code>
 shows the contents of the current directory.</para></section>

<section id="cd"><title>Function &cd;</title>
<para><code>(&cd; &path-r;)</code> sets the current working directory,
 <code>(&cd;)</code> returns it.
<variablelist>
<!-- #if defined(PATHNAME_UNIX) -->
<varlistentry><term>&unix-only;</term>
 <listitem><simpara><code>(&cd; [&path-r;])</code>
   manages the current directory.</simpara></listitem></varlistentry>
<!-- #else -->
<varlistentry><term>&win32-only;</term>
 <listitem><simpara><code>(&cd; [&path-r;])</code>
   manages the current device and the current directory.
   </simpara></listitem></varlistentry>
<!-- #endif -->
</variablelist></para></section>

<section id="default-dir"><title>Function &default-dir;</title>
<para><code>(&default-dir;)</code> is equivalent to <code>(&cd;)</code>.
 <code>(&setf; (&default-dir;) &path-r;)</code> is equivalent to
 <code>(&cd; &path-r;)</code>, except for the return value.</para></section>

<section id="make-dir">
 <title>Function <function>EXT:MAKE-DIRECTORY</function></title>
<para><code>(<function>EXT:MAKE-DIRECTORY</function> &dir-r;)</code>
 creates a new subdirectory.</para></section>

<section id="delete-dir"><title>Function &delete-dir;</title>
<para><code>(&delete-dir; &dir-r;)</code>
 removes an (empty) subdirectory.</para></section>

<section id="rename-dir"><title>Function &rename-dir;</title>
<para><code>(&rename-dir; <replaceable>old-directory</replaceable>
  <replaceable>new-directory</replaceable>)</code> renames a
 subdirectory to a new name.</para></section>
</section>
</chapter>


<chapter id="streams"><title>Streams <ulink role="clhs" url="chap-21"/></title>

<section id="streams-interactive"><title>Interactive Streams
 <ulink role="clhs" url="sec_21-1-1-1-3"/></title>

<para>Interactive streams are those whose next input might depend on a
 prompt one might output.</para>

<section id="stream-stdio-init">
  <title>Initialization of Standard Streams</title>

<para>When run interactively, &clisp; creates a single <quote>terminal</quote>
 &stream-t; and binds &terminal-io-var; to it.
 All other standard streams (&standard-input-var;, &standard-output-var;
 &error-output-var;, &trace-output-var;, &query-io-var;, &debug-io-var;)
 are &synonym-stream-t;s pointing to &terminal-io-var;.
 This has the benefit of avoiding unwanted blank lines from &fresh-line;,
 see <xref linkend="newline-convention"/>.</para>

<para>However, there may be situations, especially in &batch-mode;,
 when one wants to use a &c-lang;-style i/o where &standard-output-var;
 and &error-output-var; point to different OS &file-des; so that they can be
 <ulink role="unix" url="utilities/xcu_chap02.html#tag_02_07">redirected</ulink>
 to files in the command line and examined separately.
 Often &clisp; can detect such situations (&stdout; and &stderr; not being
 the terminal) and handle them just as expected.
 However, there may be cases when one needs to do something like:
<programlisting language="lisp">
(&setq; &standard-input-var; (&make-stream; &input-k;)
      &standard-output-var; (&make-stream; &output-k; &buffered; &t;)
      &error-output-var; (&make-stream; &error-k; &buffered; &t;))
</programlisting> in the &script; or &init-function;.</para>
</section>

</section>

<section id="terminal"><title>Terminal interaction</title>

<para>See also <xref linkend="screen"/>.</para>

<!-- #ifdef GNU_READLINE -->
<section id="readline"><title>Command line editing with &readline;</title>
 <subtitle><emphasis role="plat-dep">Only in &clisp; linked against the
   &readline; library.</emphasis></subtitle>

 <para>Input through &terminal-io-var; uses the &readline; library.
  Arrow keys can be used to move within the input history.
  The &tab-c; key completes the &symbol-t; name or
  &pathname-t; that is being typed.
  See <ulink url="&readline-link;rluserman.html">readline user
  manual</ulink> for general details and
  <olink targetdoc="man" targetptr="completion"/> for &clisp;-specific
  extensions.</para>
 <warning><simpara>The &readline; library is &not-e; used (even when
   &clisp; is linked against it) if the &stdin; and &stdout; do not both
   refer to the same terminal.
   This is determined by the function <function>stdio_same_tty_p</function>
   in file <filename role="clisp-cvs">src/stream.d</filename>.
   In some exotic cases, e.g., when running under &gdb; in
   an <command>rxvt</command> window under &cygwin;, this may be
   determined incorrectly.</simpara></warning>
 <para>See also <xref linkend="readline-mod"/>.</para>

<formalpara id="readline-config"><title>Linking against &readline;</title>
 <para>For &clisp; to use &readline; it has to be detected by
  the &configure; process.<itemizedlist>
   <listitem><para>If you run it as
     <screen>&sh-prompt; ./configure --with-readline</screen>
     it will fail if it cannot find a valid modern &readline;
     installation.</para></listitem>
   <listitem><simpara>If you use the option
     <option>--without-readline</option>, it will not even try to
     find &readline;.</simpara></listitem>
   <listitem><simpara>The default behavior
     (<option>--with-readline=default</option>) is to use &readline; if
     it is found and link &clisp; without it otherwise.
  </simpara></listitem></itemizedlist>
  You can find out whether &readline; has been detected by running
  <screen>&sh-prompt; <command role="unix">grep</command> HAVE_READLINE config.h</screen>
  in your build directory.</para></formalpara>
</section>
<!-- #endif -->

<!-- #if defined(KEYBOARD) -->
<section id="with-kbd"><title>Macro &with-kbd;</title>
<subtitle>&unix-w32-only;</subtitle>
<para>&terminal-io-var; is not the only stream that
 communicates directly with the user: During execution of the body of a
 <code>(&with-kbd; . &body-r;)</code> form,
 <firstterm>&kbd-in;</firstterm> is the &stream-t; that reads the
 keystrokes from the keyboard.
 It returns every keystroke in detail as an &input-char; with the
 following slots (see <xref linkend="input-char"/> for accessing them):
<variablelist>
 <varlistentry><term>&ch-r;</term>
  <listitem><simpara>the &character-t; for standard keys
    (accessed with &character;)</simpara>
   <note><para>For non-standard keys &character; &sig-err;, use &char-key;:
<programlisting language="lisp">
(&with-kbd;
 (&loop; :for &ch-r; = (&read-char; &kbd-in;)
   :for &key-r; = (&or-m; (&char-key; &ch-r;) (&character; &ch-r;))
   :do (&print; (&list; &ch-r; &key-r;))
   :when (&eql; &key-r; #\Space) :return (&list; &ch-r; &key-r;)))
</programlisting></para></note></listitem></varlistentry>
 <varlistentry><term>&key-r;</term>
  <listitem><para>the key name, for non-standard keys
    (accessed with &char-key;):
    <variablelist>
     <!-- #if defined(UNIX) || defined(WIN32) -->
     <varlistentry><term>&unix-w32-only;</term>
      <listitem><informaltable id="unix-kbd-keys" frame="all">
        <tgroup cols="2" colsep="1" rowsep="1" align="center">
         &key-value-header;<tbody>
          <row><entry><keycode>F1</keycode>..<keycode>F12</keycode></entry>
           <entry><constant>:F1</constant>..<constant>:F12</constant>
          </entry></row>
          <row><entry><keycode>Insert</keycode></entry>
           <entry><constant>:INSERT</constant></entry></row>
          <row><entry><keycode>Delete</keycode></entry>
           <entry><constant>:DELETE</constant></entry></row>
          <row><entry><keycode>Home</keycode></entry>
           <entry>&home-k;</entry></row>
          <row><entry><keycode>End</keycode></entry>
           <entry>&end-k;</entry></row>
          <row><entry><keycode>Center</keycode></entry>
           <entry><constant>:CENTER</constant></entry></row>
          <row><entry><keycode>PgUp</keycode></entry>
           <entry><constant>:PGUP</constant></entry></row>
          <row><entry><keycode>PgDn</keycode></entry>
           <entry><constant>:PGDN</constant></entry></row>
          <row><entry>Arrow keys</entry>
           <entry><constant>:LEFT</constant> <constant>:RIGHT</constant>
            <constant>:UP</constant> <constant>:DOWN</constant></entry></row>
     </tbody></tgroup></informaltable></listitem></varlistentry>
     <!-- #endif -->
 </variablelist></para></listitem></varlistentry>
 <varlistentry><term><replaceable>bits</replaceable></term>
  <listitem><para><variablelist>
     <!-- #ifdef WIN32 -->
     <varlistentry><term>&hyper-k;</term>
      <listitem><simpara>(&win32-only;) if a non-standard key.
        These keys are:
        <!-- #ifdef WIN32 -->
        <emphasis>[&win32;]:</emphasis>
        Function keys, cursor keypads, numeric keypad.
        <!-- #endif -->
     </simpara></listitem></varlistentry>
     <varlistentry><term>&super-k;</term>
      <listitem><simpara>(&win32-only;) if pressed together with &shift;
        key(s) and if the keystroke would have been different without
        &shift;.</simpara></listitem></varlistentry>
     <!-- #endif -->
     <varlistentry><term>&control-k;</term>
      <listitem><simpara>if pressed together with the &ctrl; key.
     </simpara></listitem></varlistentry>
     <!-- #ifdef WIN32 -->
     <varlistentry><term>&meta-k;</term>
      <listitem><simpara>(&win32-only;) if pressed together with the
        &alt; key.</simpara></listitem></varlistentry>
     <!-- #endif -->
 </variablelist></para></listitem></varlistentry>
 <varlistentry><term><replaceable>font</replaceable></term>
  <listitem><simpara>Always &zero;.</simpara></listitem></varlistentry>
</variablelist>
This keyboard input is not echoed on the screen.  During execution of a
<code>(&with-kbd; . &body-r;)</code> form, no input from
&terminal-io-var; or any synonymous stream should be requested.</para>
 <warning><para>Since &input-char; is &not-e; a subtype of
   &character-t;, &read-line; on &kbd-in; is illegal.</para></warning>
</section>
<!-- #endif -->

</section>

<section id="bin-io"><title>Binary Input and Output</title>

<section id="bin-input"><title>Binary input, &read-byte;,
  &rd-integer; &amp; &rd-float;</title>

<para>The function <code>(&rd-integer; &stream-r;
    &eltype-r; &optional-amp; &endianness; &eof-ep; &eof-v;)</code>
 reads a multi-byte &integer-t; from &stream-r;, which should be a
 &stream-t; with &stream-element-type; &ubyte-8;.
 &eltype-r; should be &type-eq; to &ubyte-n;,
 where &n-r; is a multiple of 8.</para>

<para><code>(&rd-integer; &stream-r; &eltype-r;)</code> is like
 <code>(&read-byte; &stream-r;)</code> if &stream-r;'s
 &stream-element-type; were set to &eltype-r;,
 except that &stream-r;'s &file-position; will increase by
 <superscript>&n-r;</superscript>/<subscript>8</subscript>
 instead of 1.</para>

<para>Together with <code>(&setf; &stream-element-type;)</code>, this
 function permits mixed character/binary input from a stream.</para>

<para>The function <code>(&rd-float; &stream-r; &eltype-r;
  &optional-amp; &endianness; &eof-ep; &eof-v;)</code> reads a
 floating-point number in &ieee-bfp; binary representation from
 &stream-r;, which should be a &stream-t; with
 &stream-element-type; &ubyte-8;.  &eltype-r; should be
 &type-eq; to &single-float-t; or &double-float-t;.</para>

<formalpara id="endianness"><title>Endianness</title>
 <para><firstterm>&endianness;
   <indexterm id="endianness-i" significance="preferred">
    <primary>endianness</primary></indexterm></firstterm>
  can be <constant>:LITTLE</constant> or <constant>:BIG</constant>.
  The default is <constant>:LITTLE</constant>, which corresponds
  to the &read-byte; behavior in &clisp;.</para></formalpara>

</section>

<section id="bin-output"><title>Binary output, &write-byte;,
  &wr-integer; &amp; &wr-float;</title>

<para>The function <code>(&wr-integer; &int-r; &stream-r; &eltype-r;
  &optional-amp; &endianness;)</code> writes a multi-byte &integer-t; to
 &stream-r;, which should be a &stream-t; with
 &stream-element-type; &ubyte-8;.  &eltype-r; should be
 &type-eq; to &ubyte-n;, where &n-r; is a multiple of 8.</para>

<para><code>(&wr-integer; &int-r; &stream-r; &eltype-r;)</code> is
 like <code>(&write-byte; &int-r; &stream-r;)</code> if &stream-r;'s
 &stream-element-type; were set to &eltype-r;, except that &stream-r;'s
 &file-position; will increase by
 <superscript>&n-r;</superscript>/<subscript>8</subscript>
 instead of 1.</para>

<para>Together with <code>(&setf; &stream-element-type;)</code>, this
  function permits mixed character/binary output to a &stream-t;.</para>

<para>The function <code>(&wr-float; <replaceable>float</replaceable>
  &stream-r; &eltype-r; &optional-amp; &endianness;)</code> writes a
 floating-point number in &ieee-bfp; binary representation to
 &stream-r;, which should be a &stream-t; with &stream-element-type;
 &ubyte-8;.  &eltype-r; should be
 &type-eq; to &single-float-t; or &double-float-t;.</para>

</section>
</section>

<section id="bulk-io"><title>Bulk Input and Output</title>

<section id="read-seq"><title>Bulk Input</title>
<para>In addition to &read-sequence;, the following two functions are provided:
<variablelist>
 <varlistentry id="rd-by-seq"><term>&rd-by-seq;
   performs multiple &read-byte; operations:</term>
 <listitem><simpara><code>(&rd-by-seq; &sequence-r;
   &stream-r; &key-amp; &start-k; &end-k; :NO-HANG :INTERACTIVE)</code>
   fills the subsequence of &sequence-r; specified by &start-k; and &end-k;
   with &integer-t;s consecutively read from &stream-r;.  It returns the
   index of the first element of &sequence-r; that was not updated (=
   &end-r; or &lt; &end-r; if the &stream-r; reached its end).
   When &no-hang; is non-&nil;, it does not block: it treats input
   unavailability as &eos;. When &no-hang; is &nil; and &interactive-r; is
   non-&nil;, it can block for reading the first byte but does not block
   for any further bytes.</simpara>
 <simpara>This function is especially efficient if &sequence-r; is a
   &ubyte-vec; and &stream-r; is a &file-pipe-socket-s;
   with &stream-element-type; &ubyte-8;.
 </simpara></listitem></varlistentry>
 <varlistentry id="rd-ch-seq"><term>&rd-ch-seq;
   performs multiple &read-char; operations:</term>
 <listitem><simpara><code>(&rd-ch-seq; &sequence-r; &stream-r; &key-amp;
    &start-k; &end-k;)</code> fills the subsequence of &sequence-r;
   specified by &start-k; and &end-k; with characters consecutively read
   from &stream-r;.  It returns the index of the first element of
   &sequence-r; that was not updated (= &end-r; or &lt; &end-r; if the
   &stream-r; reached its end).</simpara>
  <simpara>This function is especially efficient if &sequence-r; is a
   &string-t; and &stream-r; is a &file-pipe-socket-s; with
   &stream-element-type; &character-t; or an &input-s; &string-stream-t;.
 </simpara></listitem></varlistentry>
</variablelist></para></section>

<section id="write-seq"><title>Bulk Output</title>
<para>In addition to &write-sequence;, the following two functions are provided:
<variablelist>
 <varlistentry id="wr-by-seq"><term>&wr-by-seq;
   performs multiple &write-byte; operations:</term>
 <listitem><simpara><code>(&wr-by-seq; &sequence-r; &stream-r;
  &key-amp; &start-k; &end-k; :NO-HANG :INTERACTIVE)</code> outputs
  the &integer-t;s of the subsequence of &sequence-r; specified by
  &start-k; and &end-k; to &stream-r;.
  When &no-hang; is non-&nil;, does not block.
  When &no-hang; is &nil; and &interactive-r; is non-&nil;, it can
  block for writing the first byte but does not block for any further
  bytes.  Returns two values: &sequence-r; and the index of the first
  byte that was not output.</simpara>
 <simpara>This function is especially efficient if &sequence-r; is a
  &ubyte-vec; and &stream-r; is a &file-pipe-socket-s; with
  &stream-element-type; &ubyte-8;.</simpara></listitem></varlistentry>
<varlistentry id="wr-ch-seq"><term>&wr-ch-seq;
  performs multiple &write-char; operations:</term>
 <listitem><simpara><code>(&wr-ch-seq; &sequence-r; &stream-r; &key-amp;
  &start-k; &end-k;)</code> outputs the characters of the subsequence of
  &sequence-r; specified by &start-k; and &end-k; to &stream-r;.
  Returns the &sequence-r; argument.</simpara>
 <simpara>This function is especially efficient if &sequence-r; is a
  &string-t; and &stream-r; is a &file-pipe-socket-s; with
  &stream-element-type; &character-t;.</simpara></listitem></varlistentry>
</variablelist></para></section>

<section id="bulk-io-rationale"><title>Rationale</title>
<para>The rationale for &rd-ch-seq;, &rd-by-seq;, &wr-ch-seq; and
 &wr-by-seq; is that some &stream-t;s support both character and binary
 i/o, and when you read into a &sequence-t; that can hold both (e.g.,
 &list-t; or &simple-vector-t;) you cannot determine which kind of
 input to use.  In such situation &read-sequence; and &write-sequence;
 &signal; an &error-t;, while &rd-ch-seq;, &rd-by-seq;, &wr-ch-seq; and
 &wr-by-seq; work just fine.</para></section>

</section>

<section id="non-block-io"><title>Non-Blocking Input and Output</title>

<para>In addition to the standard functions &listen; and
 &read-char-no-hang;, &clisp; provides the following functionality
 facilitating non-blocking input and output, both binary and
 character.</para>

<variablelist>
 <varlistentry id="rcwhp"><term><code>(&rcwhp; &stream-r;)</code></term>
  <listitem><simpara>&rcwhp; queries the stream's input status.
  It returns &nil; if &read-char; and &peek-char; with a
  <replaceable>peek-type</replaceable> of &nil; will return immediately.
  Otherwise it returns &t;.  (In the latter case the standard
  &listen; function would return &nil;.)</simpara>
  <simpara>Note the difference with <code>(&not-f; (&listen;
  &stream-r;))</code>: When the &eos; is reached, &listen; returns
  &nil;, whereas &rcwhp; returns &nil;.</simpara>
  <simpara>Note also that &rcwhp; is not a good way to test for &eos;:
  If &rcwhp; returns &t;, this does not mean that the &stream-r; will
  deliver more characters.  It only means that it is not known at this
  moment whether the &stream-r; is already at &eos;, or will deliver
  more characters.</simpara></listitem></varlistentry>
 <varlistentry id="rbla"><term><code>(&rbla; &stream-r;)</code></term>
  <listitem><simpara>To be called only if &stream-r;'s
   &stream-element-type; is &ubyte-8; or &sbyte-8;.
   Returns &t; if &read-byte; would return immediately with an
   &integer-t; result.
   Returns &eof-k; if the &eos; is already known to be reached.
   If &read-byte;'s value is not available immediately, returns &nil;
   instead of waiting.</simpara></listitem></varlistentry>
 <varlistentry id="rbwhp"><term><code>(&rbwhp; &stream-r;)</code></term>
  <listitem><simpara>To be called only if &stream-r;'s
   &stream-element-type; is &ubyte-8; or &sbyte-8;.
   Returns &nil; if &read-byte; will return immediately.
   Otherwise it returns true.</simpara></listitem></varlistentry>
 <varlistentry id="rbnh"><term><code>(&rbnh; &stream-r; &optional-amp;
    &eof-ep; &eof-v;)</code></term>
  <listitem><simpara>To be called only if &stream-r;'s
   &stream-element-type; is &ubyte-8; or &sbyte-8;.
   Returns an &integer-t; or does &eos; handling, like &read-byte;,
   if that would return immediately.
   If &read-byte;'s value is not available immediately, returns &nil;
   instead of waiting.</simpara></listitem></varlistentry>
</variablelist>

<note id="listen-byte"><title>&listen; on binary streams</title>
 <para>The &ansi-cl; specification for &listen; mentions <quote>character
   availability</quote> as the criterion that determines the return value.
  Since a &character-t; is <emphasis>never</emphasis> available on a
  binary &stream-t; (i.e., a stream with &stream-element-type; being a
  subtype of &integer-t;), &listen; returns &nil; for such streams.
  (You can use &so-status; to check binary streams).
  Any other behavior would be hard to make consistent: consider a bivalent
  stream, i.e., a &stream-t; that can be operated upon by both
  &read-char; and &read-byte;.
  What should &listen; return on such a stream if what is actually available
  on the stream at the moment is only a part of a multi-byte character?
  Right now one can use first &so-status; to check if anything at all is
  available and then use &listen; to make sure that a full &character-t;
  is actually there.</para></note>

</section>

<section id="newline-convention"><title>Newline Convention</title>

<section id="nl-question"><title>Should programs output a newline before
  or after each line of output?</title>

<para>The answer is complicated. There is an antagonism between
 the <quote>old Lisp way</quote> of outputting a newline before the
 line's contents (exemplified by the functions &print; and &pprint;) and
 the <quote>Unix way</quote> of outputting a newline after the line's
 contents. Which one is <quote>right</quote>?</para>

<para>A newline convention is, by definition, a consistent way to use
 the &terpri; and &fresh-line; functions or - in &format; notation -
 &format-percent; and &format-amp; directives in such a way that the
 resulting output is properly subdivided into lines.</para>

<para>Three newline conventions are conceivable:</para>
<orderedlist numeration="upperalpha">
 <listitem><simpara>Print a newline before the line, and nothing after it.
   As a format string: <quote role="format">~%First line.~%Second line.</quote>
 </simpara></listitem>
 <listitem><simpara>Print a newline if needed before the line,
   and a newline always after it. As a format string:
   <quote role="format">~&amp;First line.~%Second line.~%</quote>
 </simpara></listitem>
 <listitem><simpara>Print nothing before the line, and a newline always
   after it. As a format string:
   <quote role="format">First line.~%Second line.~%</quote>
</simpara></listitem></orderedlist>

<para>The most important criterion is interoperability.  Two newline
conventions are interoperable if, when parts of a program use one of the
convention and other parts of the program use the other conventions,
lines are still properly separated.  It is easily seen that &nlcA; and
&nlcB; are interoperable, &nlcB; and &nlcC; are interoperable as well,
but &nlcA; and &nlcC; are not interoperable: When an output with
convention &nlcA; is followed by output in convention &nlcC;, two lines
are appended without a line separator.  This should not happen.</para>

<para>Therefore, in what follows, we consider five kinds of programs:
<itemizedlist><listitem><simpara>&nlcA;: using convention &nlcA; exclusively,
</simpara></listitem>
<listitem><simpara>&nlcAB;: mixing conventions &nlcA; and &nlcB;,
</simpara></listitem>
<listitem><simpara>&nlcB;: using convention &nlcB; exclusively,
</simpara></listitem>
<listitem><simpara>&nlcBC;: mixing conventions &nlcB; and &nlcC;,
</simpara></listitem>
<listitem><simpara>&nlcC;: using convention &nlcC; exclusively.
</simpara></listitem></itemizedlist></para>

<para>Which of these five kinds of programs operation is satisfactory?
Let us consider different criteria:<orderedlist numeration="arabic">
 <listitem><simpara>Do extra blank lines occur during normal operation?
 </simpara></listitem>
 <listitem><simpara>What happens if &fresh-line; prints a newline when
   it is not needed, i.e. when it cannot tell for sure whether the
   current column is 0?  (This situation happens, for example, when
   logging to a file: After the user has entered a line interactively,
   the column on screen is 0, but since the input has not been echoed in
   the log file, the column in the log file is usually not 0, and
   &fresh-line; &must-e; output a newline. Then a blank
   line is visible on the screen.)</simpara></listitem>
 <listitem><simpara>What happens if &fresh-line; omits a newline when it
   would be needed?
   (This is more rare, but can happen, for example, when standard output
   and standard error are different streams but are joined outside the
   Lisp implementation, at the OS level.
   Such as in <command>lisp | cat</command>.)</simpara></listitem>
 <listitem><para>Is it possible to reliably output a blank line
     before or after a paragraph of text? I.e. what happens with
   <orderedlist numeration="upperalpha"><listitem>
     <orderedlist numeration="arabic"><listitem><simpara>
        <quote role="format">~%~%First line.~%Second line.</quote>
      </simpara></listitem><listitem><simpara>
        <quote role="format">~%First line.~%Second line.~%</quote>
    </simpara></listitem></orderedlist></listitem>
    <listitem><orderedlist numeration="arabic"><listitem><simpara>
        <quote role="format">~&amp;~%First line.~%Second line.~%</quote>
      </simpara></listitem><listitem><simpara>
        <quote role="format">~&amp;First line.~%Second line.~%~%</quote>
    </simpara></listitem></orderedlist></listitem>
    <listitem><orderedlist numeration="arabic"><listitem><simpara>
        <quote role="format">~%First line.~%Second line.~%</quote>
      </simpara></listitem><listitem><simpara>
        <quote role="format">First line.~%Second line.~%~%</quote>
 </simpara></listitem></orderedlist></listitem></orderedlist></para></listitem>
 <listitem><simpara>Is it possible to optimize away blank lines?
   I.e. is it possible to avoid a blank line even though another piece
   of code uses one of A1 ... C2, without risking that adjacent lines be
   unseparated?</simpara></listitem>
</orderedlist></para></section>

<section id="nl-trad-analysis"><title>Analysis</title>
<orderedlist numeration="arabic">
 <listitem><itemizedlist>
   <listitem><simpara>&nlcA;: No extra blank lines.</simpara></listitem>
   <listitem><simpara>&nlcAB;: An extra blank line each time one
     switches from convention &nlcB; to &nlcA;.</simpara></listitem>
   <listitem><simpara>&nlcB;: No extra blank lines.</simpara></listitem>
   <listitem><simpara>&nlcBC;: No extra blank lines.</simpara></listitem>
   <listitem><simpara>&nlcC;: No extra blank lines.</simpara></listitem>
 </itemizedlist></listitem><listitem><itemizedlist>
   <listitem><simpara>&nlcA;: No extra blank lines.</simpara></listitem>
   <listitem><simpara>&nlcAB;: Blank lines can occur when
     convention &nlcB; is used.</simpara></listitem>
   <listitem><simpara>&nlcB;: Blank lines can occur.</simpara></listitem>
   <listitem><simpara>&nlcBC;: Blank lines can occur when
     convention &nlcB; is used.</simpara></listitem>
   <listitem><simpara>&nlcC;: No extra blank lines.</simpara></listitem>
 </itemizedlist></listitem><listitem><itemizedlist>
   <listitem><simpara>&nlcA;: No problem.</simpara></listitem>
   <listitem><simpara>&nlcAB;: Lines can be unseparated when one
     switches from convention &nlcA; to &nlcB;.</simpara></listitem>
   <listitem><simpara>&nlcB;: No problem.</simpara></listitem>
   <listitem><simpara>&nlcBC;: No problem.</simpara></listitem>
   <listitem><simpara>&nlcC;: No problem.</simpara></listitem>
 </itemizedlist></listitem><listitem><itemizedlist>
   <listitem><simpara>&nlcA;: No problem.</simpara></listitem>
   <listitem><simpara>&nlcAB;: The blank line is omitted when using
     A2 before switching to &nlcB;.</simpara></listitem>
   <listitem><simpara>&nlcB;: No problem.</simpara></listitem>
   <listitem><simpara>&nlcBC;: No problem.</simpara></listitem>
   <listitem><simpara>&nlcC;: No problem.</simpara></listitem>
 </itemizedlist></listitem><listitem><itemizedlist>
   <listitem><simpara>&nlcA;: Yes, using
     <quote role="format">~&amp;First line.~%Second line.</quote>
     eats a previous blank line.</simpara></listitem>
   <listitem><simpara>&nlcAB;: Not really: Using
     <quote role="format">~&amp;First line.~%Second line.</quote>
     may eat a previous blank line or a following blank line, but you
     cannot know in advance which one.</simpara></listitem>
   <listitem><simpara>&nlcB;: Yes, using
     <quote role="format">~&amp;First line.~%Second line.</quote>
     eats a following blank line.</simpara></listitem>
   <listitem><simpara>&nlcBC;: Impossible.</simpara></listitem>
   <listitem><simpara>&nlcC;: Impossible.
     To optimize blank lines in case &nlcC; would require the opposite of
     &fresh-line;, namely a conditional newline that is annullated if the
     <emphasis>next</emphasis> output on the stream will be a
     newline. (&elastic-newline;, see below.)</simpara></listitem>
</itemizedlist></listitem></orderedlist>
</section>

<section id="nl-conclusion"><title>Conclusion</title>

<para>Each approach has its advantages and disadvantages.</para>

<para>When used globally (i.e. no interoperability requirements),
 &nlcA;, &nlcB;, &nlcC; can be compared as follows:<itemizedlist>
  <listitem><simpara>&nlcA; and &nlcC; are equally perfect if eating
    blank lines is not a requirement.</simpara></listitem>
  <listitem><simpara>If eating blank lines is desirable, &nlcA; is perfect.
  </simpara></listitem>
  <listitem><simpara>&nlcB; is not so good, because it is suboptimal in case 2.
</simpara></listitem></itemizedlist></para>

<para>For &clisp; built-ins, however, the interoperability requirement
 with both &nlcA; and &nlcC; is a major requirement. Therefore we have
 to choose &nlcB;, and accept the drawbacks:<itemizedlist>
  <listitem><simpara>&nlcAB;: An extra blank line each time one
    switches from convention &nlcB; to &nlcA;.</simpara></listitem>
  <listitem><simpara>&nlcB;: When logging to a file, blank lines can
    occur.</simpara></listitem>
  <listitem><simpara>&nlcAB;: When joining two output streams into
    one, lines can be unseparated.</simpara></listitem>
  <listitem><simpara>&nlcAB;: Blank lines after a paragraph can be
    eaten by &clisp;.</simpara></listitem>
  <listitem><simpara>&nlcAB;: Optimizing blank lines is not really
    possible.</simpara></listitem></itemizedlist>
 And to minimize the drawbacks, we recommend the user programs to use
 approach &nlcB; or &nlcC;, but not &nlcA;.</para>

<para>Another drawback of &nlcB; is, however, that in interactive sessions
 the cursor is nearly always positioned at the beginning of a line,
 pointing the user's focus to the wrong point and taking away a screen
 line.</para>
</section>

<section id="nl-solution"><title>Solution</title>

<para>To solve this, we introduce the concept of an <firstterm>elastic
  newline</firstterm>, output by the function &elastic-newline;.
 This is the converse of &fresh-line;: It waits for the next character
 and outputs a newline when the next character is not a newline; then
 the next character is processed normally.
 As a &format; directive, we write it &format-dot;.
 &elastic-newline; followed by &fresh-line; leads to exactly one newline
 always.</para>

<para>Elastic newline leads to a slightly different newline convention:</para>

<itemizedlist><listitem><simpara>&nlcBp;:
   Print a newline if needed before the line, and a newline if needed after it.
   As a format string:
   <quote role="format">~&amp;First line.~%Second line.~.</quote>
</simpara></listitem></itemizedlist>

<para>The five programs being considered are now:</para><itemizedlist>
 <listitem><simpara>&nlcA;: using convention &nlcA; exclusively,
 </simpara></listitem>
 <listitem><simpara>&nlcABp;: mixing conventions &nlcA; and &nlcBp;,
 </simpara></listitem>
 <listitem><simpara>&nlcBp;: using convention &nlcBp; exclusively,
 </simpara></listitem>
 <listitem><simpara>&nlcBpC;: mixing conventions &nlcBp; and &nlcC;,
 </simpara></listitem>
 <listitem><simpara>&nlcC;: using convention &nlcC; exclusively,
</simpara></listitem></itemizedlist></section>

<section id="nl-elnl-analysis"><title>Elastic Newline Analysis</title>

<orderedlist numeration="arabic"><listitem><itemizedlist>
   <listitem><simpara>&nlcA;: No extra blank lines.</simpara></listitem>
   <listitem><simpara>&nlcABp;: No extra blank lines.</simpara></listitem>
   <listitem><simpara>&nlcBp;: No extra blank lines.</simpara></listitem>
   <listitem><simpara>&nlcBpC;: No extra blank lines.</simpara></listitem>
   <listitem><simpara>&nlcC;: No extra blank lines.</simpara></listitem>
 </itemizedlist></listitem><listitem><itemizedlist>
   <listitem><simpara>&nlcA;: No extra blank lines.</simpara></listitem>
   <listitem><simpara>&nlcABp;: Blank lines can occur when
     convention &nlcBp; is used.</simpara></listitem>
   <listitem><simpara>&nlcBp;: Blank lines can occur.</simpara></listitem>
   <listitem><simpara>&nlcBpC;: Blank lines can occur when
     convention &nlcBp; is used.</simpara></listitem>
   <listitem><simpara>&nlcC;: No extra blank lines.</simpara></listitem>
 </itemizedlist></listitem><listitem><itemizedlist>
   <listitem><simpara>&nlcA;: No problem.</simpara></listitem>
   <listitem><simpara>&nlcABp;: Lines can be unseparated when one
     switches from convention &nlcA; to &nlcBp;.</simpara></listitem>
   <listitem><simpara>&nlcBp;: Lines can be unseparated when one
     switches from one stream to another without performing a
     &force-output;. This is a general problem with buffered streams;
     &clisp;'s &fresh-line; contains a workaround that is limited to
     &standard-output-var; and &error-output-var;.</simpara></listitem>
   <listitem><simpara>&nlcBpC;: No problem.</simpara></listitem>
   <listitem><simpara>&nlcC;: No problem.</simpara></listitem>
 </itemizedlist></listitem><listitem><itemizedlist>
   <listitem><simpara>&nlcA;: No problem.</simpara></listitem>
   <listitem><simpara>&nlcABp;: The blank line is omitted when
     using A2 before switching to &nlcBp; or when using B2 before switching
     to &nlcA;.</simpara></listitem>
   <listitem><simpara>&nlcBp;: No problem.</simpara></listitem>
   <listitem><simpara>&nlcBpC;: No problem.</simpara></listitem>
   <listitem><simpara>&nlcC;: No problem.</simpara></listitem>
 </itemizedlist></listitem><listitem><itemizedlist>
   <listitem><simpara>&nlcA;: Yes, using
     <quote role="format">~&amp;First line.~%Second line.</quote>
     eats a previous blank line.</simpara></listitem>
   <listitem><simpara>&nlcABp;: Not really: Using
     <quote role="format">~&amp;First line.~%Second line.</quote>
     may eat a previous blank line or a following blank line, but you
     cannot know in advance which one.</simpara></listitem>
   <listitem><simpara>&nlcBp;: Yes, using
     <quote role="format">~&amp;First line.~%Second line.</quote>
     eats a following blank line.</simpara></listitem>
   <listitem><simpara>&nlcBpC;: Impossible.</simpara></listitem>
   <listitem><simpara>&nlcC;: Yes, using
     <quote role="format">First line.~%Second line.~.</quote>
     eats a following blank line.</simpara></listitem>
</itemizedlist></listitem></orderedlist>

<para>Now criterium 1 is satisfied perfectly. We therefore choose
 &nlcBp;, not &nlcB;, for use inside &clisp;, and programs can use
 either &nlcA; or &nlcC; without problems during normal operation.</para>
</section>
</section>

<section id="stream-extfmt"><title>Function &stream-external-format;</title>
<para>&stream-external-format; is &setf;able: <code>(&setf;
  (&stream-external-format; &stream-r; [&direction-r;]) &encoding-r;)</code>,
 &direction-r; can be &input-k;, &output-k;, or &nil;.
 If no &direction-r; is given, the operation is nonrecursive.</para>
<para>This will &not-e; work on &terminal-io-var; et al, use &term-enc;
 instead.</para></section>

<section id="stream-eltype"><title>Function &stream-element-type;</title>

<para>&stream-element-type; is &setf;able. The &stream-element-type; of
  &stream-t;s created by the functions &open;, &mk-pipe-in;
  &mk-pipe-out;, &mk-pipe-io;, &so-accept;, &so-connect;
  can be modified, if the old and the new &stream-element-type;s are either
 <itemizedlist><listitem><simpara>both equivalent to &character-t; or
    &ubyte-8; or &sbyte-8;; or</simpara></listitem>
  <listitem><simpara>both equivalent to &ubyte-n; or &sbyte-n;, with the
    same &n-r;.</simpara></listitem></itemizedlist></para>

<para>Functions &stream-element-type; and <code>(&setf;
 &stream-element-type;)</code> are &generic-function-t;s, see
 <xref linkend="gray"/>.</para>

<warning id="stream-eltype-stdio"><simpara>&clisp; expects to be able to
  do &character-t; i/o on standard streams like &terminal-io-var;,
  &standard-output-var;, &standard-input-var;, &error-output-var;,
  &query-io-var; et al, thus it is a &very-e; bad idea
  to change their &stream-element-type; even when you can. Use
  &make-stream; instead, see <xref linkend="bin-stdio"/>.</simpara></warning>

<section id="bin-stdio"><title>Binary input from &standard-input-var;</title>

<para>Note that you cannot change &stream-element-type; for some
 built-in streams, such as <link linkend="terminal">terminal streams</link>,
 which is normally the value of &terminal-io-var;.
 Since &standard-input-var; normally is a &synonym-stream-t; pointing
 to &terminal-io-var;, you cannot use &read-byte; on it.</para>

<para>Since <ulink url="http://hoohoo.ncsa.uiuc.edu/cgi/">CGI</ulink>
 (Common Gateway Interface) provides the form data for
 <command>METHOD="POST"</command> on the &stdin;,
 and the server will &not-e; send you an &eos; on the end of the data,
 you will need to use
 <code>(&getenv; <envar>"CONTENT_LENGTH"</envar>)</code>
 to determine how much data you should read from &stdin;.
 &clisp; will detect that &stdin; is not a terminal and create a regular
 &file-stream-t; which can be passed to <code>(&setf;
 &stream-element-type;)</code>.
 To test this functionality interactively,
 you will need to open the standard input in the binary mode:
<programlisting language="lisp">
(let ((buf (&make-array; (&parse-integer; (&getenv; "CONTENT_LENGTH"))
                       :element-type '&ubyte-8;)))
  (&with-open-stream; (in (&make-stream; &input-k; &eltype; '&ubyte-8;))
    (&read-sequence; buf in))
  buf)
</programlisting></para>
</section>
</section>

<section id="make-stream"><title>Function &make-stream;</title>
<para>Function &make-stream; creates a Lisp stream out of an OS &file-des;:
 <code>(&make-stream; &object-r; &key-amp; &direction-k;
  &eltype; &extfmt; &buffered;)</code></para>
<para>&object-r; designates an OS handle (a &file-des;),
 and should be one of the following: <variablelist>
  <varlistentry><term>number</term>
   <listitem><simpara>denotes the &file-des; of this value
  </simpara></listitem></varlistentry>
  <varlistentry><term>&input-k;</term><listitem><simpara>denotes &clisp;
    process standard input, that is, the &file-des; corresponding to &stdin;
    (0 on &unix;)</simpara></listitem></varlistentry>
  <varlistentry><term>&output-k;</term><listitem><simpara>denotes &clisp;
    process standard output, that is, the &file-des; corresponding to &stdout;
    (1 on &unix;)</simpara></listitem></varlistentry>
  <varlistentry><term>&error-k;</term><listitem><simpara>denotes &clisp;
    process error output, that is, the &file-des; corresponding to &stderr;
    (2 on &unix;)</simpara></listitem></varlistentry>
  <varlistentry><term>&stream-t;</term>
   <listitem><simpara>denotes the handle of this stream, which should be
     a &file-stream-t; or a &socket-stream;</simpara></listitem></varlistentry>
</variablelist></para>

<warning id="make-stream-warn-buffering"><title>Beware of buffering!</title>
 <para>When there are several Lisp &stream-t;s backed by the same OS
  &file-des;, the behavior may be highly confusing when some of the
  Lisp streams are &buffered;.  Use &force-output; for &out-s;s,
  and <link linkend="bulk-io">bulk input</link> for &in-s;s.</para></warning>

<para>The handle is duplicated (with &dup;),
 so it is safe to &close; a &stream-t; returned by &make-stream;.</para>
</section>

<section id="file-pos"><title>Function &file-position;</title>

<para>&file-position; works on any &file-stream-t;.</para>

<!-- #if defined(WIN32) || (defined(UNIX) && (O_BINARY!= 0)) -->
<variablelist>
 <varlistentry><term>&win32-only;</term>
<listitem><simpara>When a &nl-s; is output to (respectively input from)
  a &file-stream-t;, its file position is increased by 2 since &nl-s; is
  encoded as &cr-c;/&lf-c; in the file.
</simpara></listitem></varlistentry></variablelist>
<!-- #endif -->
</section>

<section id="elastic-newline"><title>Function &elastic-newline;</title>

<para>The function <code>(&elastic-newline; [&stream-r;])</code> is like
 &fresh-line; but the other way around: It outputs a conditional newline
 on &stream-r;, which is canceled if the <emphasis>next</emphasis>
 output on &stream-r; happens to be a newline.  More precisely, it
 causes a newline to be output right before the next character is
 written on &stream-r;, if this character is not a newline.
 The newline is also output if the next operation on the stream is
 &fresh-line;, &finish-output;, &force-output; or &close;.</para>

<para>The functionality of &elastic-newline; is also available through
 the &format; directive &format-dot;.</para>

<para>A technique for avoiding unnecessary blank lines in output is to
 begin each chunk of output with a call to &fresh-line; and to terminate it
 with a call to &elastic-newline;.</para>

<para>See also <xref linkend="newline-convention"/>.</para>

</section>

<section id="open"><title>Function &open;</title>

<para>&open; accepts an additional keyword &buffered;.</para>

<variablelist><title>The acceptable values for the arguments to the
   &file-pipe-socket-s; functions</title>
 <varlistentry id="eltype"><term>&eltype;</term>
  <listitem><simpara>types equivalent to &character-t; or
    &ubyte-n;, &sbyte-n;; if the stream is to be
    un&buffered;, &n-r; must be a multiple of 8.</simpara>
   <simpara>If &n-r; is not a multiple of 8, &clisp; will use the
    specified number of bits for i/o, and write the file length
    (as a number of &n-r;-bit bytes) in the preamble.</simpara>
   <simpara>This is done to ensure the input/output consistency:
    suppose you open a file with &eltype; of <literal
    role="type">(&unsigned-byte-t; 3)</literal> and write 7 bytes
    (i.e., 21 bit) there.
    The underlying OS can do input/output only in whole 8-bit bytes.
    Thus the OS will report the size of the file as 3 (8-bit) bytes.
    Without the preamble &clisp; will have no way to know how many
    3-bit bytes to read from this file - 6, 7 or 8.</simpara>
   <simpara>See also <xref linkend="stream-eltype"/>.</simpara>
 </listitem></varlistentry>
 <varlistentry id="extfmt"><term>&extfmt;</term>
  <listitem><simpara>&encoding;s, (constant) &symbol-t;s in the
    &charset-pac; package, &string-t;s (denoting &iconv;-based encodings),
    the symbol &default-k;, and the &line-term; keywords
    &unix-k;, &mac-k;, &dos-k;.  The default encoding is &def-file-enc;.
    This argument determines how the lisp &character-t; data is
    converted to/from the 8-bit bytes that the underlying OS uses.</simpara>
   <simpara>See also <xref linkend="stream-extfmt"/>.</simpara>
 </listitem></varlistentry>
 <varlistentry id="buffered"><term>&buffered;</term>
  <listitem><para>&nil;, &t;, or &default-k;.
    Have &clisp; manage an internal buffer for input or output (in
    addition to the buffering that might be used by the underlying OS).
    Buffering is a known general technique to significantly speed up i/o.
  <itemizedlist>
   <listitem><simpara>for functions that create &socket-stream;s and
    <link linkend="pipe">pipes</link>, &default-k; is equivalent to
    &t; on the input side and to &nil; on the output side; if you are
    transmitting a lot of data then using buffering
    will significantly speed up your i/o;</simpara></listitem>
   <listitem><simpara>for functions that <link linkend="open">open</link>
    files, &default-k; means that buffered file streams will be returned
    for regular files and (on &unix;) block-devices, and unbuffered file
    streams for special files.</simpara></listitem>
  </itemizedlist>
  Note that some files, notably those on the <filename>/proc</filename>
  filesystem (on &unix; systems), are actually, despite their innocuous
  appearance, special files, so you might need to supply an explicit
  &buffered; &nil; argument for them.  Actually, &clisp; detects that
  the file is a <filename>/proc</filename> file, so that one is covered,
  but there are probably more strange beasts out there!
</para></listitem></varlistentry>
</variablelist>

<simplesect id="reopen"><title>Variable &reopen;</title>
<para>When an already opened file is opened again, and &not-e; both the
 existing and the new &stream-t;s are read-only (i.e., &direction-k; is
 &input-k; or <constant>:INPUT-IMMUTABLE</constant>), the streams can
 mess up each other and produce unexpected results.
 The user variable <firstterm>&reopen;</firstterm> controls how &clisp;
 handles the situation and can take 4 values: <variablelist>
  <varlistentry><term>&nil;</term><listitem><simpara>
     do nothing: do not even check that there are other &stream-t;s
     pointing to the same file</simpara></listitem></varlistentry>
  <varlistentry><term>&warn;</term><listitem><simpara>&signal; a
     &warning-t; and proceed</simpara></listitem></varlistentry>
  <varlistentry><term>&close;</term><listitem><simpara>&close;
     the <emphasis>other</emphasis> &stream-t;s and proceed
     (this could be dangerous and is not generally recommended)
  </simpara></listitem></varlistentry>
  <varlistentry><term>&error; (default)</term><listitem><simpara>&signal;
     a &cont-err;</simpara></listitem></varlistentry>
</variablelist></para></simplesect>

</section>

<section id="clear-input"><title>Function &clear-input;</title>
<para>Calling &clear-input; on a &stream-t; removes the &eos; state,
 thus making it available for further input.</para>
<para>This allows reading from a file as it is being appended to,
as if with <command role="unix">tail -f</command>.</para>
</section>

<section id="close"><title>Function &close;</title>

<para>Function &close; is a &generic-function-t;, see
 <xref linkend="gray"/>.</para>

<para>When the &abort-k; argument is non-&nil;, &close; will not
 &sig-err; even when the underlying OS call fails.</para>

<para>&get-output-stream-string; returns the same value after
 &close; as it would before it.</para>

<para>&close; on an already closed &stream-t; does nothing and returns
 &t;.</para>

<para>If you do not &close; your &stream-t; explicitly, it will be
 closed at &gc;ion time automatically
 (with <code>(&close; &stream-r; &abort-k; &t;)</code>).
 This is &not-e; recommended though because &gc;ion is not deterministic.
 Please use &with-open-stream; etc.</para>

</section>

<section id="open-stream-p"><title>Function &open-stream-p;</title>
<para>Function &open-stream-p; is a &generic-function-t;, see
 <xref linkend="gray"/>.</para>
</section>

<section id="broadcast-stream"><title>Class &broadcast-stream-t;</title>

<para>&input-stream-p; and &interactive-stream-p; return false for
 &broadcast-stream-t;s.</para>

</section>

<section id="stream-buffer"><title>Functions
  <firstterm><function>EXT:MAKE-BUFFERED-INPUT-STREAM</function>
   <indexterm id="stream-buffer-i" significance="preferred">
    <primary>MAKE-BUFFERED-INPUT-STREAM</primary></indexterm></firstterm> and
  <firstterm><function>EXT:MAKE-BUFFERED-OUTPUT-STREAM</function>
   <indexterm id="stream-buffer-o" significance="preferred">
    <primary>MAKE-BUFFERED-OUTPUT-STREAM</primary></indexterm></firstterm>
 </title>

<formalpara><title><code>(EXT:MAKE-BUFFERED-OUTPUT-STREAM
   &func-r;)</code></title>
<para>Returns a buffered &out-s;.
 &func-r; is a &function-t; expecting one argument, a &simple-string-t;.
 &write-char; collects the &character-t;s in a &string-t;, until a
 newline character is written or &force-output;/&finish-output; is called.
 Then &func-r; is called with a &simple-string-t; as argument,
 that contains the characters collected so far.
 &clear-output; discards the characters collected so far.</para>
</formalpara>

<formalpara><title><code>(EXT:MAKE-BUFFERED-INPUT-STREAM &func-r;
   &mode-r;)</code></title>
<para>Returns a buffered &in-s;.
 &func-r; is a &function-t; of 0 arguments that returns
 either &nil; (stands for &eos;) or up to three values
 &string-r;, &start-r;, &end-r;.
 &read-char; returns the &character-t;s of the current &string-r; one
 after another, as delimited by &start-r; and &end-r;, which default to
 &zero; and &nil;, respectively.
 When the &string-r; is consumed, &func-r; is called again.
 The &string-r; returned by &func-r; should not be changed by the user.
 &func-r; should copy the &string-r; with &copy-seq; or &subseq; before
 returning if the original &string-r; is to be modified.
 &mode-r; determines the behavior of &listen;
 when the current &string-r; buffer is empty:
 <variablelist>
  <varlistentry><term>&nil;</term>
   <listitem><simpara>the stream acts like a &file-stream-t;,
     i.e. &func-r; is called</simpara></listitem></varlistentry>
  <varlistentry><term>&t;</term>
   <listitem><simpara>the stream acts like an interactive stream without
     &eos;, i.e. one can assume that further characters will always
     arrive, without calling &func-r;</simpara></listitem></varlistentry>
  <varlistentry><term>&function-t;</term>
   <listitem><simpara>this &function-t; tells, upon call, if further
     non-empty &string-r;s are to be expected.</simpara></listitem>
 </varlistentry></variablelist>
 &clear-input; discards the rest of the current &string-r;,
 so &func-r; will be called upon the next &read-char; operation.
</para></formalpara>
</section>

<section id="stream-handles"><title>Function
  <function>EXT:STREAM-HANDLES</function></title>

<para>The function <code>(EXT:STREAM-HANDLES &stream-r;)</code> returns
two values:<orderedlist>
<listitem><simpara>The OS &file-des; for the &input-s; side of the
&stream-r;, or &nil; if the &stream-r; is an &output-s;-only &stream-t;
or if there is no &file-des; associated with it.</simpara></listitem>
<listitem><simpara>The OS &file-des; for the &output-s; side of the
&stream-r;, or &nil; if the &stream-r; is an &input-s;-only &stream-t;
or if there is no &file-des; associated with it.</simpara></listitem>
</orderedlist></para>
<warning><para>It is dangerous to &close; the &file-des;s returned by
this function.  This may lead to <constant role="errno">EBADF</constant>
OS &error-t;s and, eventually, segmentation faults.  Always use &close;
on the original Lisp &stream-r;s instead.</para></warning>
</section>

</chapter>


<chapter id="printer"><title>Printer <ulink role="clhs" url="chap-22"/></title>

<section id="multi-rep"><title>Multiple Possible Textual Representations
  <ulink role="clhs" url="sec_22-1-1-1"/></title>

<simplesect id="pr-closure"><title>Variable &pr-closure;</title>
<para>An additional variable &pr-closure; controls whether compiled and
 interpreted functions (closures) are output in detailed form.
 If &pr-closure; is non-&nil;, a readable syntax is used for closures:
<variablelist><varlistentry><term>interpreted closures</term>
<listitem><simpara>&sharp-S;(&function-t; ...)</simpara></listitem>
</varlistentry><varlistentry><term>compiled closures</term>
<listitem><simpara><literal role="data">#Y(...)</literal> (this is what you
would see if you open a &clisp; &fasl-file; in a text editor)</simpara>
</listitem></varlistentry></variablelist></para>
<para>This feature is turned off by &with-standard-io-syntax; because
 it is easy to get wrong (see below) and non-portable.</para>
<warning><para>Closures often refer to value cells or other entities from the
&lex-env;.  The correct operation of a &function-t; may depend on the access
to the same value cells as some other, related &function-t;s.
If you want to &write; and &read; back &function-t;s so that their semantics
is preserved, you have to &write; and &read; &all-e; &function-t;s that share
some structure in the &lex-env; <emphasis>together</emphasis>, and you have to
either bind &print-readably-var; to &t; or use &with-standard-io-syntax;:
<programlisting language="lisp">
(&setf; (&values; my-pop my-push)
      `(&let; ((storage ()))
         (&values; (&lambda-m; () (&pop; storage))
                 (&lambda-m; (x) (&push; x storage)))))
(&let; ((pair (&read-from-string;
             (&with-standard-io-syntax;
               (&let; ((&pr-closure; &t;))
                 (&prin1-to-string; (&cons; my-pop my-push)))))))
   (&setq; my-pop-1 (&car; pair)
         my-push-1 (&cdr; pair)))
</programlisting>
Note that <function>my-pop</function> and <function>my-push</function>
share environment between themselves but &not-e; with
<function>my-pop-1</function> and <function>my-push-1</function> which
can be easily seen if you do <programlisting language="lisp">
(&let; ((&pr-closure; &t;) (&print-circle-var; &t;))
  (&print; (&list; my-pop my-push my-pop-1 my-push-1)))
</programlisting> but which is not at all obvious from the usual
&sharp-lt; output.</para></warning>
<para>&pr-closure; is initially set to &nil;.</para></simplesect>

<simplesect id="pr-rpars"><title>Variable &pr-rpars;</title>
<para>An additional variable &pr-rpars; controls
 the output of the right (closing) parentheses.
 If &pr-rpars; is non-&nil;, closing parentheses which do not fit onto
 the same line as the the corresponding opening parenthesis are output
 just below their corresponding opening parenthesis, in the same column.
 </para>
<para>&pr-rpars; is initially set to &nil;.</para></simplesect>

<simplesect id="pr-indent"><title>Variable &pr-indent;</title>
<para>An additional variable &pr-indent; controls the indentation of
 lists that span more than one line.
 It specifies by how many characters items within the list will be
 indented relative to the beginning of the list.</para>
<para>&pr-indent; is initially set to <literal>1</literal>.</para></simplesect>

<simplesect id="ppr-first-newline"><title>Variable &ppr-first-newline;</title>
<para>An additional variable &ppr-first-newline; controls
 pretty-printing of multi-line objects.
 When &ppr-first-newline; is non-&nil;,
 and the current line already has some characters on it,
 and the next object will be printed on several lines,
 and it does not start with a &nl-s;,
 then a &nl-s; is printed before the object.
 E.g., when you type <code>(&format; &t; "return value: ~S~%" &v-r;)</code>
 you want want to see a terse one-line output when &v-r; is something
 short (like &zero; or &nil; or &t;), but you probably want to see
 something nice, like <screen>
return value:
(long list which does not fit
 on one line)</screen>
instead of <screen>
return value: (long list which does not fit
 on one line)</screen> when it does not.</para>
<para>&ppr-first-newline; has no effect if &print-pretty-var; is &nil;.</para>
<para>&ppr-first-newline; is initially set to &t;.</para></simplesect>

</section>

<section id="write-float-decimal"><title>Printing Floats
  <ulink role="clhs" url="sec_22-1-3-1-3"/></title>

<para>In the absence of &write-float-decimal;, floating point numbers
 are output in radix 2.  This function is defined in &floatprint-lisp;
 and is not available if you run &clisp; without a &mem-image; (which
 you should never do anyway!)</para>

<para>If &print-readably-var; is true, &read-default-float-format-var;
 has no influence on the way &float-t;s are printed.</para>

</section>

<section id="spacecharprint"><title>Printing Characters
  <ulink role="clhs" url="sec_22-1-3-2"/></title>

<para>Characters are printed as specified in &ansi-cl; using
 &sharp-back;, with one exception: when &pri-esc; is in effect,
 the space character is printed as
 <quote><computeroutput>#\Space</computeroutput></quote> when the
 variable &spacecharprint; is &nil;.
 When &spacecharprint; is non-&nil;, it is printed as
 <quote><computeroutput>#\&nbsp;</computeroutput></quote>; this is how
 &ansi-cl; specifies it.</para>

</section>

<section id="sym-pack-prefix"><title>Package Prefixes for Symbols
  <ulink role="clhs" url="sec_22-1-3-3-1"/></title>

<formalpara id="pr-sym-pack-prefix"><title>Variable &pr-sym-pack-prefix;</title>
 <para>When &pr-sym-pack-prefix; is non-&nil;, the package
  prefix is not the &package-name; but the shortest (nick)name as
  returned by &package-shortest-name;.  This variable is ignored when
  &print-readably-var; is non-&nil;.</para></formalpara>

</section>

<section id="print-vector"><title>Printing Other Vectors
  <ulink role="clhs" url="sec_22-1-3-7"/></title>

<para>When &print-readably-var; is true, other vectors are written as
 follows: if the &array-element-type; is &t-t;, the syntax
 <computeroutput>#(&x1-r; ... &xn-r;)</computeroutput> is used.
 Otherwise, the syntax <computeroutput>#A(&eltype-r;
  &dimensions-r; &cont-r;)</computeroutput> is used.</para>

</section>

<section id="print-array"><title>Printing Other Arrays
  <ulink role="clhs" url="sec_22-1-3-8"/></title>

<para>When &print-readably-var; is true, other arrays are written as
 follows: if the &array-element-type; is &t-t;, the syntax
 <computeroutput>&sharp-A; &cont-r;</computeroutput> is used.
 Otherwise, the syntax <computeroutput>#A(&eltype-r; &dimensions-r;
 &cont-r;)</computeroutput> is used.</para>

<para>As explicitly permitted by this section, specialized &bit-t; and
 &character-t; &array-t;s are printed with the innermost lists generated
 by the printing algorithm being instead printed using &bit-vector-t; and
 &string-t; syntax, respectively.</para>

<formalpara id="pr-empty-arr-ansi"><title>Variable &pr-empty-arr-ansi;</title>
<para>Empty &array-t;s, i.e., arrays with no elements and zero
 &array-total-size; (because one of its dimensions is zero) are printed
 with the readable syntax <computeroutput>#A(&eltype-r; &dimensions-r;
 &cont-r;)</computeroutput>, unless the variable &pr-empty-arr-ansi; is
 non-&nil;, in which case the arrays are printed using the
 &ansi-cl;-prescribed syntax <computeroutput>&sharp-A; &cont-r;</computeroutput>
 which often loses the dimension information.</para></formalpara>

<section id="pathprint"><title>Printing Pathnames
  <ulink role="clhs" url="sec_22-1-3-11"/></title>

<para>Pathnames are printed as follows: If &print-escape-var; is &nil;,
 only the namestring is printed; otherwise it is printed with the
 &sharp-P; syntax, as per the &ansi-cl; issue &iss276;.
 But, if &print-readably-var; is true, we are in trouble as &sharp-P; is
 ambiguous (which is verboten when &print-readably-var; is true), while
 being mandated by the &ansi-cl;.
 Therefore, in this case, &clisp;'s behavior is determined by the value
 of &pathprint;: when it is &nil;, we print pathnames like this:
<computeroutput>&sharp-minus;CLISP &sharp-P;"..."
&sharp-plus;CLISP &sharp-S;(&pathname-t; ...)</computeroutput>.
Otherwise, when the variable &pathprint; is non-&nil;, the
&sharp-P; notation is used as per <ulink role="clhs" url="sec_1-5-1-4-1"/>
<quote>Resolution of Apparent Conflicts in Exceptional Situations</quote>.
</para>

<note><simpara>The &sharp-S; notation for &pathname-t;s is used
  extensively in the &hyperspec; (see examples for &pathname;,
  &pathnamep;, &parse-namestring; et al), but was decided against, see
  &iss260;.</simpara></note>

<warning><simpara>When both &print-readably-var; and &pathprint; are
  non-&nil; and the namestring will be parsed to a dissimilar object
  (with the current value of &parsedot;), an &error-t; of type
  &print-not-readable-t; is &signal;ed.</simpara></warning>

</section>

</section>

<section id="clpp"><title>The Lisp Pretty Printer
  <ulink role="clhs" url="sec_22-2"/></title>

<para>The Lisp Pretty Printer implementation is &not-e; perfect yet.
 &pprint-logical-block; does not respect &print-lines-var;.</para>

<section id="pp-dispatch"><title>Pretty Print Dispatch Table
  <ulink role="clhs" url="sec_22-2-1-4"/></title>

<para>A <ulink url="clhs/glo">pprint dispatch table</ulink> is a &cons;
 of a &symbol-t; &print-pprint-dispatch-var; and an &alist; which maps
 types into priorities and print functions.
 Their use is strongly discouraged because of the performance issues:
 when &print-pprint-dispatch-var; is non-trivial and &print-pretty-var;
 is non-&nil;, printing of every object requires a lookup in the table,
 which entails many calls to &typep; (which cannot be made fast
 enough).</para>

</section>

</section>

<section id="print-formatted"><title>Formatted Output
  <ulink role="clhs" url="sec_22-3"/></title>
 <subtitle>Function &format;</subtitle>

<para>The additional &format; instruction
 <firstterm><literal>~!</literal><indexterm id="format-bang" significance="preferred">
   <primary>&format;</primary><secondary>~!</secondary></indexterm></firstterm>
 is similar to &format-slash;, but avoids putting a function name into a
 string, thus it is &read; in the current &package-var;, so, even if the
 function is not interned in the &clu-pac; package, you might not need
 to specify the package explicitly.
 <code>(&format; &stream-r; "~arguments!" &func-r; &object-r;)</code> is
  equivalent to <code>(&funcall; &func-r; &stream-r; &object-r;
  <replaceable>colon-modifier-p</replaceable>
  <replaceable>atsign-modifier-p</replaceable> &args-r;)</code>.</para>

<para>The additional &format; instruction
 <firstterm><literal>~.</literal><indexterm id="format-dot" significance="preferred">
   <primary>&format;</primary><secondary>~.</secondary></indexterm></firstterm>
 is a kind of opposite to <code>~&amp;</code>: It outputs a conditional
 newline, by calling the function &elastic-newline;.
 <code>~&n-r;.</code> outputs <replaceable>n-1</replaceable> newlines
 followed by an &elastic-newline;. <code>~0.</code> does nothing.</para>

<para>&format; &format-r; and &format; &format-rs; can output only
 integers in the range <code>|&n-r;| &lt;
  <replaceable>10<superscript>66</superscript></replaceable></code>.
 The output is in English, according to the American conventions, and
 these conventions are identical to the British conventions only in the
 range <code>|&n-r;| &lt;
  <replaceable>10<superscript>9</superscript></replaceable></code>.</para>

<para>&format; &format-c; does not output the character itself, only the
 instruction how to type the character.</para>

<para>For &format; &format-e; and &format; &format-g;, the value of
 &read-default-float-format-var; does not matter if &print-readably-var;
 is true.</para>

<para>&format; &format-t; can determine the current column of any
 built-in stream.</para>

</section>

<section id="write"><title>Functions &write; &amp; &write-to-string;</title>
<para>The functions &write; and &write-to-string; have an additional
 keyword argument <constant>:CLOSURE</constant> which is used to bind
 &pr-closure;.</para></section>

<!-- //Commented out from the source code.
<section id="print-object"><title>Generic Function &print-object;</title>
<para>The function &print-object; verifies the &ansi-cl; requirement that its
return value is the same as its first argument. It issues a warning if one of
the &print-object; methods yields a wrong return value. To get rid of such a
warning, you need to fix the source code of the incriminated method.</para>
</section>
-->

<section id="print-unreadable-object">
 <title>Macro &print-unreadable-object;</title>
<formalpara id="pr-unreadable-ansi"><title>Variable &pr-unreadable-ansi;</title>
<para>The macro &print-unreadable-object;, when invoked without body forms,
 suppresses the trailing space if only the type is to be printed, and
 suppresses the leading space if only the identity is to be printed.  This
 behaviour can be turned off set setting the variable &pr-unreadable-ansi;
 to a non-&nil; value: in this case, a trailing or leading space are output,
 as prescribed by &ansi-cl;.</para></formalpara>
</section>

<section id="print-misc"><title>Miscellaneous Issues</title>

<para>&print-case-var; controls the output not only of symbols, but also
 of characters and some <literal role="#lt">unreadable</literal> objects.</para>

<variablelist>
<varlistentry><term>&unix-w32-only;</term>
<listitem><simpara>&print-pretty-var; is initially &nil; but set to &t;
 in &config-lisp;.  This makes screen output prettier.
 </simpara></listitem></varlistentry>
</variablelist>

<para>&print-array-var; is initially set to &t;.</para>

</section>
</chapter>

<chapter id="reader"><title>Reader <ulink role="clhs" url="chap-23"/></title>

<section id="rt-case"><title>Effect of Readtable Case on the Lisp Reader
  <ulink role="clhs" url="sec_23-1-2"/></title>

<para>When the value of <code>(&readtable-case;
 <replaceable>readtable</replaceable>)</code> is
 <constant>:INVERT</constant>, it applies to the package name and the
 symbol name of a symbol separately (not to the entire token at once).
 An alternative to the use of &readtable-case; is the use of the
 &case-sensitive-k; option of &make-package; and &defpackage;.</para>

</section>

<section id="recursive-p"><title>The &rec-p; argument
  <ulink role="clhs" url="sec_23-1-3-2"/></title>

<para>When non-&nil; &rec-p; argument is passed to a top-level &read;
 call, an &err-sig;.</para>

</section>

</chapter>


<chapter id="system"><title>System Construction
  <ulink role="clhs" url="chap-24"/></title>

<para>The compiler can be called not only by the functions &compile;,
 &compile-file-my; and &disassemble;, but also by the declaration
 &compile-decl;.</para>

<section id="compilefile"><title>Function &compile-file;</title>

<para>&compile-file; compiles a file to a platform-independent
 &bytecode;:
<programlisting language="lisp">
(&compile-file; &filename-r; &key-amp; &outfile-k; :LISTING &extfmt;
                            ((&warnings-k; &compile-warn;) &compile-warn;)
                            ((&verbose-k; &compile-verbose-var;) &compile-verbose-var;)
                            ((&print-k; &compile-print-var;) &compile-print-var;))
</programlisting></para>

<variablelist id="compile-file-arguments">
 <title>Options for &compile-file;</title>
<varlistentry><term>&filename-r;</term>
 <listitem><simpara>the file to be compiled, should be a &path-des;.
 </simpara></listitem></varlistentry>
<varlistentry><term>&outfile-k;</term>
 <listitem><simpara>should be &nil; or &t; or a &path-des; or an
   &out-s;.  The default is &t;.</simpara></listitem></varlistentry>
<varlistentry><term><constant>:LISTING</constant></term>
 <listitem><simpara>should be &nil; or &t; or a &path-des; or an
   &out-s;.  The default is &nil;.</simpara></listitem></varlistentry>
<varlistentry><term>&extfmt;</term>
 <listitem><simpara>the &encoding; of the &filename-r;.
</simpara></listitem></varlistentry>
<varlistentry><term>&warnings-k;</term>
 <listitem><simpara>specifies whether warnings should also appear on the
   screen.</simpara></listitem></varlistentry>
<varlistentry><term>&verbose-k;</term>
 <listitem><simpara>specifies whether error messages should also appear
   on the screen.</simpara></listitem></varlistentry>
<varlistentry><term>&print-k;</term>
 <listitem><simpara>specifies whether an indication which forms are
   being compiled should appear on the screen.
</simpara></listitem></varlistentry>
</variablelist>

<para>The variables <firstterm>&compile-warn;
  <indexterm id="compile-warn" significance="preferred">
   <primary>*COMPILE-WARNINGS*</primary></indexterm></firstterm>
 (initially set to &t;), &compile-verbose-var; (initially set to &t;,
 affected by &opt-v;) &compile-print-var; (initially set to &nil;,
 affected by &opt-v;) provide defaults for the &warnings-k;, &verbose-k;,
 &print-k; keyword arguments, respectively, and are bound by &compile-file;
 to the values of the arguments, i.e., these arguments are recursive.</para>

<section id="compile-file-output"><title>Output files</title>
<para>For each input file (default file type: &lisp-file;)
 the following files are generated:
<informaltable id="compile-file-new-files-table" frame="all">
 <tgroup cols="4" colsep="1" rowsep="1" align="center">
  <colspec colnum="4" align="left"/>
  <thead><row><entry>File</entry><entry>When</entry>
  <entry>Default file type</entry><entry>Contents</entry></row></thead><tbody>
 <row><entry>output file</entry>
   <entry>only if &outfile-k; is not &nil;</entry><entry>&fasl-file;</entry>
   <entry>can be loaded using the &load-my; function</entry></row>
 <row><entry>auxiliary output file</entry>
   <entry>only if &outfile-k; is not &nil;</entry><entry>&lib-file;</entry>
   <entry>used by &compile-file; when compiling a &require-my; form referring
    to the input file</entry></row>
 <row><entry>listing file</entry>
   <entry>only if <constant>:LISTING</constant> is not &nil;</entry>
   <entry><filename>#P".lis"</filename></entry>
   <entry>disassembly of the output file</entry></row>
 <row><entry>&c-lang; output file</entry>
   <entry>only if &outfile-k; is not &nil;</entry>
   <entry><filename>#P".c"</filename></entry>
   <entry>&ffi-pac;; this file is created only if the source contains
    &ffi-pac; forms</entry></row>
</tbody></tgroup></informaltable></para>

<warning id="c-file-overwrite"><para>If you have two files in the same
directory - &foolisp-f; and <filename>#P"foo.c"</filename>, and you
compile the first file with &clisp;, the second file will be
<emphasis>clobbered</emphasis> if you have any &ffi-pac; forms in
the first one!</para></warning>
</section>

<section id="compile-file-return"><title>Return values</title>
<para>As per &ansi-cl;, &compile-file; returns 3 values:
<variablelist><varlistentry><term>output-truename</term>
 <listitem><simpara>the truename of the output &fasl-file;, or &nil;
  if the file could not be created, in which case the compilation is
  considered to have failed</simpara></listitem></varlistentry>
<varlistentry><term>warnings-p</term>
 <listitem><simpara>&nil; if no conditions of type &error-t; or &warning-t;
  were detected during compilation, and the number of such conditions otherwise
</simpara></listitem></varlistentry>
<varlistentry><term>failure-p</term>
 <listitem><simpara>&nil; if no conditions of type &error-t; or &warning-t;
  (other than &style-warning-t;) were detected during compilation,
  and the number of such conditions otherwise
</simpara></listitem></varlistentry></variablelist>
Since &clisp; tends to be relatively garrulous with warnings
 (see, e.g., <xref linkend="flocont"/>), the non-&nil; tertiary return value
 (called <replaceable>failure-p</replaceable> by the &ansi-cl;)
 does &not-e; indicate a failure of compilation.
The correct way to check whether &compile-file; has failed is the
 <emphasis>primary</emphasis> return value.</para>
</section>

</section>

<section id="compile-file-path">
 <title>Function &compile-file-pathname;</title>
<para>The default for the &outfile-k; argument is
 &t;, which means &fasl-file;.</para></section>

<section id="require"><title>Function &require;</title>

<para>The function &require; receives as the optional argument either
 a &pathname-t; or a &list-t; of &pathname-t;s: files to be &load-my;ed
 if the required module is not already present.</para>

<section id="require-return"><title>Return value</title>
<para>When the module is already present, &nil; is returned;
 otherwise returns the &truename; which was loaded to satisfy the &require;ment
 (or &list-t; thereof iff the second argument is a &list-t;).</para>
</section>

<section id="require-search"><title>Additional &load-my; locations</title>

<para>In addition to (and &before-e;) &load-paths;, &require; tries to
 find the file to &load-my; in the following locations:<itemizedlist>
  <listitem><simpara>&dynmod-only;</simpara>
   <simpara>The system-wide external modules directory
    <code>(&merge-pathnames; "dynmod/" &libdir;)</code>.</simpara></listitem>
  <listitem><simpara>&dynmod-only;</simpara>
   <simpara>The user external modules directory <code>(&merge-pathnames;
     "dynmod/" &user-libdir;)</code>
    (when &user-libdir; is non-&nil;).</simpara></listitem>
  <listitem><simpara>When &require; was called while &load-my;ing, the
    directory with the file being loaded (i.e., <code>(&make-pathname;
     :name &nil; :type &nil; :defaults &load-truename-var;)</code>).
</simpara></listitem></itemizedlist></para>
</section>

<section id="module-providers"><title>User variable &module-providers;</title>
<para>When &require; is called without the second (pathname) argument,
 the elements of the &module-providers; &list-t; are called one by one
 on the first (module name) argument until one of them returns non-&nil;.
 If all of them return &nil;, &load-my; is called as described
 <link linkend="require-search">above</link>.</para>
<para>Initially the lisp is empty; <code>(require "&asdf-mod;")</code>
 modifies it (<emphasis role="plat-dep">if &clisp; was configured with the
 option <option>--with-module=asdf</option></emphasis>).</para></section>

<section id="lib-files"><title>Interaction with &compile-file-my;</title>

<para>At compile time, <code>(&require; &foo-f;)</code>
forms are treated specially: &load-paths; is searched for
&foolisp-f; &and-e; <filename>#P"foo.lib"</filename>.
If the latest such file is a &lisp-file;, it is compiled;
otherwise the &lib-file; is loaded.
If neither is found, <code>(&require; &foo-f;)</code> is called.</para>
<warning id="module-user-file-name-conflict"><para>It is a &very-e; bad
idea to name your files the same way as &clisp; modules
(whether <link linkend="included-modules">system-supplied</link>
or <olink targetdoc="clink" targetptr="opt-install">user-installed</olink>)
because then &require-my; will use different files at compile
and execution times.</para></warning>

<para>The &lib-file; is a <quote>header</quote> file which contains the
constant, variable, inline and macro definitions necessary for
compilation of the files that &require; this file, but not the function
definitions and calls that are not necessary for that.
Thus it is &not-e; necessary to either enclose &require; forms in
&eval-when; or to load the required files in the makefiles: if you have
two files, &foolisp-f; and <filename>#P"bar.lisp"</filename>, and the
latter requires the former, you can write in your &make-file;:
<programlisting language="make">
all: foo.fas bar.fas

foo.fas: foo.lisp
	clisp &opt-c; foo

bar.fas: bar.lisp foo.fas
	clisp &opt-c; bar
</programlisting>
instead of the more cumbersome (and slower, since &lib-file;s are
usually smaller and load faster that &fasl-file;s):
<programlisting language="make">
bar.fas: bar.lisp foo.fas
        &clisp-cmd; &opt-i; foo &opt-c; bar
</programlisting>
Thus, you do not need to <code>(&load-my; &foo-f;)</code> in order
to <code>(&compile-file-my; <filename>#P"bar.lisp"</filename>)</code>.
If memory is tight, and if &foolisp-f; contains only a few inline
functions, macros, constants or variables, this is a space and time
saver.  If &foolisp-f; does a lot of initializations or side effects
when being loaded, this is important as well.</para></section>

</section>

<section id="loadfile"><title>Function &load;</title>

<para>&load; accepts four additional keyword arguments &echo-k;,
 &compiling-k;, &extra-file-types-k;, and &obsolete-action-k;.</para>

<programlisting language="lisp">
(&load; &filename-r; &key-amp; ((&verbose-k; &load-verbose-var;) &load-verbose-var;)
                    ((&print-k; &load-print-var;) &load-print-var;)
                    ((&echo-k; &load-echo;) &load-echo;) &if-does-not-exist;
                    ((&compiling-k; &load-comp;) &load-comp;) &extra-file-types-k;
                    ((&obsolete-action-k; &load-obs;) &load-obs;)
                    (ignore-pathname-defaults nil))
</programlisting>

<variablelist>
 <varlistentry><term>&verbose-k;</term>
  <listitem><simpara>causes &load; to emit a short message that a file is
    being loaded.  The default is &load-verbose-var;, which is initially
    &t;, but can be changed by the &opt-v; option.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&print-k;</term>
  <listitem><simpara>causes &load; to print the value of each form.  The
    default is &load-print-var;, which is initially &nil;, but can be
    changed by the &opt-v; option.</simpara></listitem></varlistentry>
 <varlistentry><term>&echo-k;</term>
  <listitem><simpara>causes the input from the file to be echoed to
    &standard-output-var; (normally to the screen).  Should there be an
    error in the file, you can see at one glance where it is.
    The default is <firstterm>&load-echo;
     <indexterm id="load-echo" significance="preferred">
      <primary>*LOAD-ECHO*</primary></indexterm></firstterm>,
     which is initially &nil;, but can be changed by the &opt-v; option.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&compiling-k;</term>
  <listitem><simpara>causes each form read to be compiled on the fly.
    The compiled code is executed at once and - in contrast to
    &compile-file-my; - not written to a file.
    The default is <firstterm>&load-comp;
     <indexterm id="load-comp" significance="preferred">
      <primary>*LOAD-COMPILING*</primary></indexterm></firstterm>,
     which is initially &nil;, but can be changed by the &opt-C; option.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&extra-file-types-k;</term>
  <listitem><simpara>Specifies the &list-t; of additional file types
    considered for loading, in addition to <firstterm>&source-types;
     <indexterm id="source-types" significance="preferred">
      <primary>*SOURCE-FILE-TYPES*</primary></indexterm></firstterm>
    (which is initially <literal role="data">("lisp" "lsp" "cl")</literal>)
    and <firstterm>&compiled-types;
      <indexterm id="compiled-types" significance="preferred">
       <primary>*COMPILED-FILE-TYPES*</primary></indexterm></firstterm>
    (which is initially <literal role="data">("fas")</literal>).
   </simpara><simpara>When &filename-r; does not specify a unique file
    (e.g., &filename-r; is &foo-f; and both &foolisp-f;
    and <filename>#P&quot;foo.fas&quot;</filename> are found in the
    &load-paths;), then the <emphasis>newest</emphasis> file is loaded.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&obsolete-action-k;</term>
  <listitem><para>Specifies the action to take when loading a
    &fasl-file; with a different &bytecode; version from the one
    supported by this &clisp; version.  The possible actions are
    <variablelist><varlistentry><term><constant>:DELETE</constant></term>
      <listitem><simpara>delete the &fasl-file; and proceed as with &nil;
     </simpara></listitem></varlistentry>
     <varlistentry><term>&error-k;</term>
      <listitem><simpara>&signal; an &error-t;
     </simpara></listitem></varlistentry>
     <varlistentry><term><constant>:COMPILE</constant></term>
      <listitem><simpara>recompile the source file (if found in &load-paths;)
        and &load; the result</simpara></listitem></varlistentry>
     <varlistentry><term>&nil; (default)</term>
      <listitem><simpara>&warn; and <link linkend="load-paths">look
         for another matching file</link>
    </simpara></listitem></varlistentry></variablelist>
    If no file can be loaded and &if-does-not-exist; is non-&nil;, an &err-sig;.
    The default is <firstterm>&load-obs;
     <indexterm id="load-obs" significance="preferred">
      <primary>*LOAD-OBSOLETE-ACTION*</primary></indexterm></firstterm>,
    which is initially &nil;.</para></listitem></varlistentry>
  <varlistentry><term><constant>:IGNORE-PATHNAME-DEFAULTS</constant></term>
  <listitem><simpara>Do not merge &default-pathname-defaults-var; to the
   argument using &merge-pathnames; (as required by &ansi-cl;) and rely
   on &load-paths; instead.</simpara></listitem></varlistentry>
</variablelist>

<para>The variables &load-verbose-var;, &load-print-var;,
&load-obs;, &load-comp;, and &load-echo; are bound by &load; when it
receives a corresponding keyword argument (&verbose-k;, &print-k;,
&obsolete-action-k;, &compiling-k;, and &echo-k;), i.e., these arguments
are recursive, just like the arguments &warnings-k;, &verbose-k;, and
&print-k; for &compile-file-my;.</para>

<para>When evaluation of a read form &sig-err;, three &restart-t;s are
 available:<variablelist><varlistentry><term><literal>SKIP</literal></term>
   <listitem><simpara>Skip this form and read the next one.
  </simpara></listitem></varlistentry>
  <varlistentry><term><literal>RETRY</literal></term>
   <listitem><simpara>Try to evaluate this form again.
  </simpara></listitem></varlistentry>
  <varlistentry><term><literal>STOP</literal></term>
   <listitem><simpara>Stop loading the file.
</simpara></listitem></varlistentry></variablelist></para>

<para>On success, &load; returns the &truename; of the file which it loaded,
 or the &filename-r; argument if it is a &stream-t; but not a &file-stream-t;.
</para>

<formalpara id="load-paths"><title>Variable &load-paths;</title>
<para>The variable &load-paths; contains a list of directories where the
 files are looked for - in addition to the specified or current
 directory - by &load-my;, &require-my;, &compile-file-my; and
 &load-logical-pathname-translations;.</para></formalpara>

</section>

<section id="features"><title>Variable &features-var;</title>

<para>The variable &features-var; initially contains the following symbols
<variablelist id="features-table"><title>Default &features-var;</title>
<varlistentry><term><constant>:CLISP</constant></term>
  <listitem><simpara>the name of this implementation
</simpara></listitem></varlistentry>
<varlistentry><term><constant>:ANSI-CL</constant></term>
 <listitem><simpara>&clisp; <ulink url="clhs/glo">purports to
    conform</ulink> to &ansi-cl;</simpara></listitem></varlistentry>
<varlistentry><term><constant>:COMMON-LISP</constant></term>
 <listitem><simpara>required by &ansi-cl;</simpara></listitem></varlistentry>
<varlistentry><term><constant>:INTERPRETER</constant></term>
 <listitem><simpara>&eval; is implemented</simpara></listitem></varlistentry>
<varlistentry><term><constant>:COMPILER</constant></term>
 <listitem><simpara>&compile; and &compile-file-my; are implemented
</simpara></listitem></varlistentry>
<!-- #ifdef SOCKET_STREAMS -->
<varlistentry><term><constant>:SOCKETS</constant></term>
 <listitem><simpara>see <xref linkend="socket"/>
</simpara></listitem></varlistentry>
<!-- #endif -->
<varlistentry><term><constant>:MT</constant></term>
 <listitem><simpara>see <xref linkend="mt"/>
</simpara></listitem></varlistentry>
<!-- #ifdef GENERIC_STREAMS -->
<varlistentry><term><constant>:GENERIC-STREAMS</constant></term>
 <listitem><simpara>see <xref linkend="gstream"/>
</simpara></listitem></varlistentry>
<!-- #endif -->
<varlistentry><term><constant>:LOGICAL-PATHNAMES</constant></term>
 <listitem><simpara><link linkend="log-path">Logical Pathnames</link>
   are implemented</simpara></listitem></varlistentry>
<!-- #ifdef DYNAMIC_FFI -->
<varlistentry><term><constant>:FFI</constant></term>
 <listitem><simpara>if a foreign function interface
   (see <xref linkend="dffi"/>) is supported
   (<emphasis role="plat-dep">Many &unix;, &win32;
    platforms only</emphasis>)</simpara></listitem></varlistentry>
<!-- #endif -->
<!-- #ifdef GNU_GETTEXT -->
<varlistentry><term><constant>:GETTEXT</constant></term>
 <listitem><simpara>if internationalization (see <xref linkend="i18n"/>)
   using the &ggettext; package is supported
   (<emphasis role="plat-dep">most &unix; platforms
    only</emphasis>)</simpara></listitem></varlistentry>
<!-- #endif -->
<!-- #ifdef ENABLE_UNICODE -->
<varlistentry><term><constant>:UNICODE</constant></term>
 <listitem><simpara>if &unicode; (ISO 10646) characters are supported
   (see <xref linkend="encoding"/>)</simpara></listitem></varlistentry>
<!-- #endif -->
<varlistentry><term><constant>:LOOP</constant></term>
 <listitem><simpara><quote>extended</quote> &loop; form is implemented
</simpara></listitem></varlistentry>
<varlistentry><term><constant>:CLOS</constant></term>
 <listitem><simpara>&clos; is implemented</simpara></listitem></varlistentry>
<varlistentry><term><constant>:MOP</constant></term>
 <listitem><simpara>&mop; is implemented</simpara></listitem></varlistentry>
<!-- #ifdef WIDE_HARD -->
<varlistentry><term><constant>:WORD-SIZE=64</constant></term>
 <listitem><simpara>if &clisp; was built for a 64-bit CPU.  This could
   be useful on platforms with 64-bit CPUs which have a 32-bit mode
   emulation (e.g., <emphasis role="platform">i386</emphasis> is
   emulated on <emphasis role="platform">x86_64</emphasis>
   and <emphasis role="platform">ia64</emphasis>) so that the user can
   decide which ABI library to load dynamically using &ffi-pac;.
</simpara></listitem></varlistentry>
<!-- #endif -->
<varlistentry><term><constant>:WIN32</constant></term>
 <listitem><simpara>if &hw; = PC (clone) and &os; = &win32;
  (Windows 95/98/Me/NT/2000/XP)</simpara></listitem></varlistentry>
<varlistentry><term><constant>:PC386</constant></term>
 <listitem><simpara>if &hw; = PC (clone).  It can be used as an
   indicator for the mainstream hardware characteristics (such as the
   existence of a graphics card with a non-graphics text mode,
   or the presence of a keyboard with arrows and
   <keysym>Insert</keysym>/<keysym>Delete</keysym> keys,
   or an ISA/VLB/PCI bus) or software characteristics (such as the
   <keycombo>&ctrl;&alt;<keysym>Delete</keysym></keycombo> keyboard
   combination).</simpara></listitem></varlistentry>
<varlistentry><term>&unix-k;</term>
 <listitem><simpara>if &os; = &unix; (in this case the &hw; is irrelevant!)
</simpara></listitem></varlistentry>
<varlistentry><term><constant>:BEOS</constant></term>
 <listitem><simpara>if &os; = &beos; (in that case &unix-k; is also present)
</simpara></listitem></varlistentry>
<varlistentry><term><constant>:CYGWIN</constant></term>
 <listitem><simpara>if &clisp; is using the &cygwin; &unix; compatibility
  layer on top of &win32; (in that case &unix-k; is also present)
</simpara></listitem></varlistentry>
<varlistentry><term><constant>:MACOS</constant></term>
 <listitem><simpara>if &os; = &macosx; (in that case &unix-k; is also present)
</simpara></listitem></varlistentry></variablelist></para>

<para>Each &module; should add the appropriate keyword, e.g.,
 <link linkend="syscalls"><constant>:SYSCALLS</constant></link>,
 <link linkend="dir-key"><constant>:DIRKEY</constant></link>,
 <link linkend="regexp-mod"><constant>:REGEXP</constant></link>,
 <link linkend="pcre"><constant>:PCRE</constant></link>, etc.</para>
</section>

<section id="featurep"><title>Function <function>EXT:FEATUREP</function>
  <ulink url="&clrfi;/clrfi-1-featurep">[CLRFI-1]</ulink></title>
<para><code>(EXT:FEATUREP &form-r;)</code> provides run-time access to
 the read-time conditionals &sharp-plus; and &sharp-minus;.
 &form-r; is a &feature-expr;.</para>
</section>

<section id="compiled-file-p"><title>Function &compiled-file-p;
  <ulink url="&clrfi;/clrfi-2-compiled-file-p">[CLRFI-2]</ulink></title>
<para><code>(&compiled-file-p; &filename-r;)</code> returns non-&nil;
 when the file &filename-r; exists, is readable, and appears to be a
 &clisp;-compiled &fasl-file; file compatible with the currently used
 &bytecode; format.</para>
<para>System definition facilities (such as &asdf; or &defsystem;) can
 use it to determine whether the file needs to be recompiled.</para>
</section>

</chapter>


<chapter id="environment"><title>Environment
  <ulink role="clhs" url="chap-25"/></title>

<section id="repl"><title>Top Level Loop
  <ulink role="clhs" url="sec_25-1-1"/></title>

<para>The debugger may be invoked through the functions
 &invoke-debugger;, &break;, &signal;, &error;, &cerror;, &warn;.
 The stepper is invoked through the macro &step;.
 Debugger and stepper execute subordinate &repl;
 (called <firstterm>break loops</firstterm>)
 which are similar to the main &repl; except for the
 <link linkend="prompt">prompt</link> and the set of available commands.
 Commands must be typed literally, in any case,
 without surrounding quotes or &whitespace;.
 Each command has a keyword abbreviation,
 indicated in the second column.</para>

<table id="debugger-main-deb-step" frame="all">
 <title>Commands common to the main loop, the debugger and the stepper</title>
 <tgroup cols="3" colsep="1" rowsep="1" align="center">
  &cmd-abbrev-oper-header;<tbody>
 <row><entry>&help;</entry><entry><command>:h</command></entry>
   <entry>print a list of available commands</entry></row>
 <row><entry><command>LocalSymbols</command></entry>
  <entry><command>:ls</command></entry><entry>print the list of
   &symbol-t;s &intern;ed in a given &package-t;.</entry></row>
</tbody></tgroup></table>

<table id="debugger-deb-step" frame="all">
 <title>Commands common to the debugger and the stepper</title>
 <tgroup cols="3" colsep="1" rowsep="1" align="center">
  &cmd-abbrev-oper-header;<tbody>
 <row><entry><command>Abort</command></entry>
   <entry><command>:a</command></entry>
   <entry>abort to the next most recent &repl;</entry></row>
 <row><entry><command>Unwind</command></entry>
   <entry><command>:uw</command></entry>
   <entry>abort to the next most recent &repl;</entry></row>
 <row><entry><command>Quit</command></entry>
   <entry><command>:q</command></entry>
   <entry>quit to the top &repl;</entry></row>
</tbody></tgroup></table>

<para>The stack is organized into frames and other stack elements.
 Usually every invocation of an interpreted function and every
 evaluation of an interpreted form corresponds to one stack frame.
 Special forms such as &let;, &let-star;, &unwind-protect; and &catch;
 produce special kinds of stack frames.</para>

<para id="cur-frame">In a break loop there is a
 <firstterm>&cur-frame;</firstterm>, which is initially the most recent
 stack frame but can be moved using the debugger
 commands <command>Up</command> and <command>Down</command>.</para>

<para>Evaluation of forms in a break loop occurs in the &lex-env; of the
 &cur-frame; and <emphasis>at the same time</emphasis> in the &dyn-env;
 of the debugger's caller.  This means that to inspect or modify a
 &lex-var; all you have to do is to move the &cur-frame; to be just
 below the frame that corresponds to the form or the function call that
 binds that variable.</para>

<formalpara id="stack-mode"><title>Stack Printing Mode</title>
<para>There is a current <firstterm>stack mode</firstterm> which defines
 in how much detail the stack is shown by the stack-related debugger
 commands (&backtrace; et al):<orderedlist>
  <listitem><simpara>All the stack elements are considered.
    This mode works fine for debugging compiled functions.</simpara></listitem>
  <listitem><simpara>All the frames are considered.</simpara></listitem>
  <listitem><simpara>Only lexical frames (frames that correspond to special
    forms that modify the &lex-env;) are considered.</simpara></listitem>
  <listitem><simpara>Only &eval; and &apply; frames are considered.
    Every evaluation of a form in the interpreter corresponds to an
    &eval; frame.  This is the default.</simpara></listitem>
  <listitem><simpara>Only &apply; frames are considered.
    Every invocation of an interpreted function corresponds to one
    &apply; frame.</simpara></listitem>
</orderedlist></para></formalpara>

<table id="debugger-deb-step-1" frame="all">
 <title>Commands common to the debugger and the stepper</title>
 <tgroup cols="3" colsep="1" rowsep="1" align="center">
  &cmd-abbrev-oper-header;<tbody>
 <row><entry><command>Error</command></entry>
  <entry><command>:e</command></entry>
  <entry>print the last error object.</entry></row>
 <row><entry><command>Inspect</command></entry>
  <entry><command>:i</command></entry>
  <entry>&inspect-my; the last error object.</entry></row>
 <row><entry><command>Where</command></entry>
  <entry><command>:w</command></entry>
  <entry>show the &cur-frame;.</entry></row>
 <row><entry><command>Up</command></entry>
  <entry><command>:u</command></entry>
  <entry>go up one frame, i.e., to the caller if in mode-5</entry></row>
 <row><entry><command>Down</command></entry>
  <entry><command>:d</command></entry>
  <entry>do down one frame, i.e., to the callee if in mode-5</entry></row>
 <row><entry><command>Top</command></entry>
  <entry><command>:t</command></entry>
  <entry>go to top frame, i.e., to the top-level form if in mode-4
 </entry></row>
 <row><entry><command>Bottom</command></entry>
  <entry><command>:b</command></entry>
  <entry>go to bottom (most recent) frame, i.e., most probably to the
   form or function that caused the debugger to be entered.</entry></row>
 <row><entry><command>Mode</command> &stack-mode;</entry>
  <entry><command>:m</command> &stack-mode;</entry>
  <entry>set the current stack printing mode</entry></row>
 <row id="frame-limit"><entry><command>Frame-limit</command> &l-r;</entry>
  <entry><command>:fl</command></entry>
  <entry>set the &frame-limit;: this many frames will be printed
   by &backtrace; at most.</entry></row>
 <row id="backtrace"><entry>&backtrace; [&stack-mode; [&l-r;]]</entry>
  <entry><command>:bt</command> [&stack-mode; [&l-r;]]</entry>
  <entry>list the stack in the given &stack-mode;, bottom frame first,
  top frame last; at most &l-r; frames are printed;
  calls &show-stack;.</entry></row>
</tbody></tgroup></table>

<para>If the &cur-frame; is an &eval; or &apply; frame, the
  following commands are available as well:</para>

<table id="debugger-eval-apply" frame="all">
 <title>Commands specific to &eval;/&apply;</title>
 <tgroup cols="3" colsep="1" rowsep="1" align="center">
  &cmd-abbrev-oper-header;<tbody>
<row><entry><command>Break+</command></entry>
 <entry><command>:br+</command></entry>
 <entry>set a breakpoint in the current frame.  When the corresponding
  form or function will be left, the debugger will be entered again, with
  the variable &trace-val; containing a list of its values.</entry></row>
<row><entry><command>Break-</command></entry>
 <entry><command>:br-</command></entry>
 <entry>remove a breakpoint from the current frame.</entry></row>
<row><entry><command>Redo</command></entry>
 <entry><command>:rd</command></entry>
 <entry>re-evaluate the corresponding form or function call. This
  command can be used to restart parts of a computation without
  aborting it entirely.</entry></row>
<row><entry><command>Return</command> &value-r;</entry>
 <entry><command>:rt</command> &value-r;</entry>
 <entry>leave the current frame, returning the given value.</entry></row>
</tbody></tgroup></table>

<table id="debugger-deb" frame="all">
 <title>Commands specific to the debugger</title>
 <tgroup cols="3" colsep="1" rowsep="1" align="center">
  &cmd-abbrev-oper-header;<tbody>
<row><entry><command>Continue</command></entry>
   <entry><command>:c</command></entry>
   <entry>continue evaluation of the program.</entry></row>
</tbody></tgroup></table>

<table id="debugger-step" frame="all">
 <title>Commands specific to the stepper</title>
 <tgroup cols="3" colsep="1" rowsep="1" align="center">
  &cmd-abbrev-oper-header;<tbody>
<row><entry><command>Step</command></entry>
   <entry><command>:s</command></entry>
   <entry>step into a form: evaluate this form in single step mode
   </entry></row>
<row><entry><command>Next</command></entry>
   <entry><command>:n</command></entry>
   <entry>step over a form: evaluate this form at once
   </entry></row>
<row><entry><command>Over</command></entry>
   <entry><command>:o</command></entry>
   <entry>step over this level: evaluate at once up to the next return
   </entry></row>
<row><entry><command>Continue</command></entry>
   <entry><command>:c</command></entry>
   <entry>switch off single step mode, continue evaluation
   </entry></row>
</tbody></tgroup></table>

<para>The stepper is usually used like this: If some form returns a
 strange value or results in an error, call <code>(&step;
 &form-r;)</code> and navigate using the
 commands <command>Step</command> and <command>Next</command> until you
 reach the form you regard as responsible.  If you are too fast (execute
 <command>Next</command> once and get the error), there is no way back;
 you have to restart the entire stepper session.  If you are too slow
 (stepped into a function or a form which certainly is OK), a couple of
 <command>Next</command> commands or one <command>Over</command> command
 will help.</para>

<section id="user-commands"><title>User-defined Commands</title>

<para>You can set <firstterm>&user-commands;</firstterm> to a list of
 &function-t;s, each returning a &list-t;
 of <firstterm>bindings</firstterm>, i.e., either a
<variablelist><varlistentry><term>&string-t;</term>
<listitem><simpara>the help string printed by &help; in addition to the
  standard &clisp; help</simpara></listitem></varlistentry>
<varlistentry><term>&cons-t; <literal role="data">(&string-t;
   . &function-t;)</literal></term>
 <listitem><simpara>the actual binding: when the user types the string,
   the function is called on the remainder of the string, i.e., the part
   of the string after the command.</simpara></listitem></varlistentry>
</variablelist> E.g.,
<programlisting language="lisp">
(setq &user-commands;
      (list (lambda () (list (format nil "~2%User-defined commands:")))
            (lambda ()
              (flet ((panic (argline)
                       (format t "don't panic~@[ because of ~A~], ~D~%"
                               (and (plusp (length argline)) argline)
                               (random 42))))
                (list (format nil "~%panic   :p    hit the panic button!")
                      (cons "panic" #'panic)
                      (cons ":p" #'panic))))
            (lambda ()
              (let ((curses #("ouch" "yuk" "bletch")))
                (flet ((swear (argline)
                         (format t "~A: ~A!~%" argline
                                 (aref curses (random (length curses))))))
                  (list (format nil "~%swear   :e    curse")
                        (cons "swear" #'swear)
                        (cons ":e" #'swear)))))))
</programlisting></para></section>

</section>

<section id="debugger"><title>Debugging Utilities
  <ulink role="clhs" url="sec_25-1-2"/></title>

<!-- #ifdef HAVE_DISASSEMBLER -->
<section id="disassemble"><title>Function &disassemble;</title>
<variablelist><varlistentry><term>&unix-only;</term>
  <listitem><simpara>&disassemble; can disassemble to machine code,
    provided that &gnu; &gdb; is present. In that case the argument may be a
   <classname>EXT:SYSTEM-FUNCTION</classname>, a &foreign-function-t;, a
   special operator handler, a &symbol-t; denoting one of these, an
   &integer-t; (address), or a &string-t;.
</simpara></listitem></varlistentry></variablelist>
</section>
<!-- #endif -->

<section id="uncompile"><title>Function &uncompile;</title>
<para>The function &uncompile; does the converse of
 &compile;: <code>(&uncompile; &func-r;)</code> reverts a compiled
 &func-r; (name), that has been entered or loaded in the same session
 and then compiled, back to its interpreted form.</para>
</section>

<section id="show-stack"><title>Function &show-stack;</title>
<para>The function &show-stack; is called by the &backtrace; command.</para>
<para>It prints to &standard-output-var; and accepts 3 optional
arguments:<orderedlist><listitem><simpara>&stack-mode;</simpara></listitem>
<listitem><simpara>&frame-limit;</simpara></listitem>
<listitem><simpara><replaceable>start-frame</replaceable></simpara></listitem>
</orderedlist></para>
<para>It can used to find out what all the threads are up to:
<programlisting language="lisp">
(&loop; :with out = &standard-output-var; :for &thr; :in (&list-threads;) :do
   (&format; out "===~A===~;" &thr;)
   (&thread-interrupt; &thr; :function
     (&lambda-m; () (&let; ((&standard-output-var; out)) (&show-stack; 1 3)))))
</programlisting>
</para></section>

<section id="documentation"><title>Function &documentation;</title>
<para>No on-line documentation is available for the system functions
 (yet), but see <xref linkend="describe"/>.</para></section>

<section id="describe"><title>Function &describe;</title>
<para>When &browser; is non-&nil;, and &clhs-root; returns a valid URL,
 &describe; on a standard &cl; symbol will point your web browser to the
 appropriate &hyperspec; page.</para>

<para>Also, when &browser; is non-&nil;, and &impnotes-root; returns a
 valid URL, &describe; on symbols and packages documented in these
 implementation notes will point your web browser to the appropriate
 page.</para>

<para>To do this, &describe; will retrieve the appropriate tables from
 &clhs-root; and &impnotes-root; on the first relevant invocation.
 These operations are logged to &http-log-stream;.</para>

<formalpara id="clhs-root"><title>Function &clhs-root;</title>
<para>Function &clhs-root; is defined in &config-lisp;.  By default it
 looks at <code>(&getenv; "CLHSROOT")</code> and &clhs-root-default;,
 but you may redefine it in &config-lisp; or &RC-file;.
 The return value should be a &string-t; terminated with a &file-slash;,
 e.g., <ulink url="&clhs;/"/> or <filename>/usr/doc/HyperSpec/</filename>.
 If the return value is &nil;, the feature is completely disabled.
 &clhs-root-default; is initialized in &config-lisp; based on
 the <option>--hyperspec</option> passed to the top-level &configure;
 script when &clisp; was built.</para></formalpara>

<formalpara id="impnotes-root"><title>Function &impnotes-root;</title>
<para>Function &impnotes-root; is defined in &config-lisp;.  By default it
 looks at <code>(&getenv; "IMPNOTES")</code> and &impnotes-root-default;,
 but you may redefine it in &config-lisp; or &RC-file;.
 The return value should be a &string-t; terminated with a &file-slash;,
 e.g., <ulink url="http://clisp.org/impnotes/"/>, or the path to
 the monolithic page, e.g., <ulink url="http://clisp.org/impnotes.html"/>
 or <filename>/usr/doc/clisp/impnotes.html</filename>.
 If the return value is &nil;, the feature is completely disabled.
</para></formalpara>
</section>

<section id="trace"><title>Macro &trace;</title>

<para><code>(&trace; &funcname-r; ...)</code> makes the
 functions &funcname-r;, ... traced.  Each &funcname-r; should be either
 a &funname; or a &list-t; <code>(&funcname-r; &key-amp;
 <constant>:SUPPRESS-IF</constant> <constant>:MAX-DEPTH</constant>
 <constant>:STEP-IF</constant> <constant>:BINDINGS</constant>
 <constant>:PRE</constant> <constant>:POST</constant>
 <constant>:PRE-BREAK-IF</constant> <constant>:POST-BREAK-IF</constant>
 <constant>:PRE-PRINT</constant> <constant>:POST-PRINT</constant>
 &print-k;)</code>, where</para>

<variablelist>
 <varlistentry><term><constant>:SUPPRESS-IF</constant> &form-r;</term>
  <listitem><simpara>no trace output as long as &form-r; is true
  </simpara></listitem></varlistentry>
 <varlistentry><term><constant>:MAX-DEPTH</constant> &form-r;</term>
  <listitem><simpara>no trace output as long as <code>(&gt;
  *trace-level* &form-r;)</code>. This is useful for tracing functions that
  are use by the tracer itself, such as &print-object;, or otherwise when
  tracing would lead to an infinite recursion.
  </simpara></listitem></varlistentry>
 <varlistentry><term><constant>:STEP-IF</constant> &form-r;</term>
  <listitem><simpara>invokes the stepper as soon as &form-r; is true
  </simpara></listitem></varlistentry>
 <varlistentry><term><constant>:BINDINGS</constant>
   ((&var-r; &form-r;)...)</term>
  <listitem><simpara>binds &var-r;s to the result of evaluation of
    &form-r;s around evaluation of all of the following forms
  </simpara></listitem></varlistentry>
 <varlistentry><term><constant>:PRE</constant> &form-r;</term>
  <listitem><simpara>evaluates &form-r; before calling the function
  </simpara></listitem></varlistentry>
 <varlistentry><term><constant>:POST</constant> &form-r;</term>
  <listitem><simpara>evaluates &form-r; after return from the function
  </simpara></listitem></varlistentry>
 <varlistentry><term><constant>:PRE-BREAK-IF</constant> &form-r;</term>
  <listitem><simpara>goes into the break loop before calling the
   function if &form-r; is true</simpara></listitem></varlistentry>
 <varlistentry><term><constant>:POST-BREAK-IF</constant> &form-r;</term>
  <listitem><simpara>goes into the break loop after return from the
   function if &form-r; is true</simpara></listitem></varlistentry>
 <varlistentry><term><constant>:PRE-PRINT</constant> &form-r;</term>
  <listitem><simpara>prints the values of &form-r; before calling the
   function</simpara></listitem></varlistentry>
 <varlistentry><term><constant>:POST-PRINT</constant> &form-r;</term>
  <listitem><simpara>prints the values of &form-r; after return from the
   function</simpara></listitem></varlistentry>
 <varlistentry><term>&print-k; &form-r;</term>
  <listitem><simpara>prints the values of &form-r; both before calling
   and after return from the function</simpara></listitem></varlistentry>
</variablelist>

<para>In all these forms you can access the following variables:
<variablelist>
 <varlistentry><term><varname>EXT:*TRACE-FUNCTION*</varname></term>
  <listitem><simpara>the traced function itself
  </simpara></listitem></varlistentry>
 <varlistentry><term><varname>EXT:*TRACE-ARGS*</varname></term>
  <listitem><simpara>the arguments to the function
  </simpara></listitem></varlistentry>
 <varlistentry><term><varname>EXT:*TRACE-FORM*</varname></term>
  <listitem><simpara>the function/macro call as form
  </simpara></listitem></varlistentry>
 <varlistentry id="trace-val"><term>&trace-val;</term>
  <listitem><simpara>after return from the function: the list of return
  values from the function call</simpara></listitem></varlistentry>
</variablelist>
and you can leave the function call with specified values by using
&return;.</para>

<para>&trace; and &untrace; are also applicable to functions
 <code>(&setf; &symbol-r;)</code> and to macros, but not to
 locally defined functions and macros.</para>

<simplesect id="trace-out"><title>Trace output</title>
<para>&trace; prints this line before evaluating the form:
<computeroutput><replaceable>trace level</replaceable>. Trace: &form-r;</computeroutput>
and after evaluating the form it prints:
<computeroutput><replaceable>trace level</replaceable>. Trace: &funcname-r; ==&gt; &res-r;</computeroutput>
where <quote>trace level</quote> is the total nesting level.
</para></simplesect>

<simplesect id="trace-indent"><title>Variable &trace-indent;</title>
<para>If you want the &trace; level to be indicated by the indentation
in addition to the printed numbers, set &trace-indent; to non-&nil;.
Initially it is &nil; since many nested traced calls will easily
exhaust the available line length.</para></simplesect>

<simplesect id="trace-eg"><title>Examples</title>

<example id="trace-call-id">
 <title>Identifying Individual Calls in &trace;</title>
<para>Suppose the trace level above is not enough for you to identify
 individual calls.  You can give each call a unique id and print it:
<programlisting language="lisp">
(defun f0 (x)
  (cond ((zerop x) 1)
        ((zerop (random 2)) (* x (f0 (1- x))))
        (t (* x (f1 (1- x))))))
<computeroutput>F0</computeroutput>
(defun f1 (x)
  (cond ((zerop x) 1)
        ((zerop (random 2)) (* x (f0 (1- x))))
        (t (* x (f1 (1- x))))))
<computeroutput>F1</computeroutput>
(defvar *f0-call-count* 0)
<computeroutput>*F0-CALL-COUNT*</computeroutput>
(defvar *id0*)
<computeroutput>*ID0*</computeroutput>
(defvar *cc0*)
<computeroutput>*CC0*</computeroutput>
(defvar *f1-call-count* 0)
<computeroutput>*F1-CALL-COUNT*</computeroutput>
(defvar *id1*)
<computeroutput>*ID1*</computeroutput>
(defvar *cc1*)
<computeroutput>*CC1*</computeroutput>
(trace (f0 :bindings ((*cc0* (incf *f0-call-count*))
                      (*id0* (gensym "F0-")))
           :pre-print (list 'enter *id0* *cc0*)
           :post-print (list 'exit *id0* *cc0*))
       (f1 :bindings ((*cc1* (incf *f1-call-count*))
                      (*id1* (gensym "F1-")))
           :pre-print (list 'enter *id1* *cc1*)
           :post-print (list 'exit *id1* *cc1*)))
;; Tracing function F0.
;; Tracing function F1.
<computeroutput>(F0 F1)</computeroutput>
(f0 10)
1. Trace: (F0 '10)
(ENTER #:F0-2926 1)
2. Trace: (F1 '9)
(ENTER #:F1-2927 1)
3. Trace: (F0 '8)
(ENTER #:F0-2928 2)
4. Trace: (F1 '7)
(ENTER #:F1-2929 2)
5. Trace: (F1 '6)
(ENTER #:F1-2930 3)
6. Trace: (F1 '5)
(ENTER #:F1-2931 4)
7. Trace: (F1 '4)
(ENTER #:F1-2932 5)
8. Trace: (F0 '3)
(ENTER #:F0-2933 3)
9. Trace: (F1 '2)
(ENTER #:F1-2934 6)
10. Trace: (F0 '1)
(ENTER #:F0-2935 4)
11. Trace: (F1 '0)
(ENTER #:F1-2936 7)
(EXIT #:F1-2936 7)
11. Trace: F1 ==> 1
(EXIT #:F0-2935 4)
10. Trace: F0 ==> 1
(EXIT #:F1-2934 6)
9. Trace: F1 ==> 2
(EXIT #:F0-2933 3)
8. Trace: F0 ==> 6
(EXIT #:F1-2932 5)
7. Trace: F1 ==> 24
(EXIT #:F1-2931 4)
6. Trace: F1 ==> 120
(EXIT #:F1-2930 3)
5. Trace: F1 ==> 720
(EXIT #:F1-2929 2)
4. Trace: F1 ==> 5040
(EXIT #:F0-2928 2)
3. Trace: F0 ==> 40320
(EXIT #:F1-2927 1)
2. Trace: F1 ==> 362880
(EXIT #:F0-2926 1)
1. Trace: F0 ==> 3628800
<computeroutput>3628800</computeroutput>
*f0-call-count*
<computeroutput>4</computeroutput>
*f1-call-count*
<computeroutput>7</computeroutput></programlisting></para></example>

</simplesect>

</section>

<section id="inspect"><title>Function &inspect;</title>

<para>The function &inspect; accepts a keyword argument
 <constant>:FRONTEND</constant>, which specifies the way &clisp; will
 interact with the user, and defaults
 to <varname>CUSTOM:*INSPECT-FRONTEND*</varname>.
<variablelist><title>Available <constant>:FRONTEND</constant>s for
   &inspect; in &clisp;</title>
 <varlistentry><term><constant>:TTY</constant></term>
  <listitem><simpara>The interaction is conducted via the &terminal-io-var;
    stream.  Please use the &help; command to get the list of all
    available commands.</simpara></listitem></varlistentry>
 <varlistentry><term><constant>:HTTP</constant></term>
  <listitem><simpara>A window in your Web browser (specified by the
    &browser-k; keyword argument) is opened and it is controlled by
    &clisp; via a &socket-stream;, using the &http; protocol.
    You should be able to use all the standard browser features.</simpara>
   <simpara>Since &clisp; is not multitasking at this time, you will not
    be able to do anything else during an &inspect; session.  Please click on
    the <userinput>quit</userinput> link to terminate the session.</simpara>
   <simpara>Please be aware though, that once you terminate an &inspect;
    session, all links in all &inspect; windows in your browser will become
    obsolete and using them in a new &inspect; session will result in
    unpredictable behavior.</simpara></listitem></varlistentry>
</variablelist></para>

<para>The function &inspect; also accepts a keyword argument &browser-k;,
 which specifies the browser used by the <constant>:HTTP</constant>
 front-end and defaults to <varname>CUSTOM:*INSPECT-BROWSER*</varname>.</para>

<para>The function &inspect; binds some
 <link linkend="clpp">pretty-printer</link> variables:
 <informaltable id="inspect-vars" frame="all">
  <tgroup cols="2" colsep="1" rowsep="1" align="left">
   <thead><row><entry>Variable</entry><entry>Bound to</entry></row></thead>
   <tbody><row><entry>&print-length-var;</entry>
     <entry><varname>CUSTOM:*INSPECT-PRINT-LENGTH*</varname></entry></row>
    <row><entry>&print-level-var;</entry>
     <entry><varname>CUSTOM:*INSPECT-PRINT-LEVEL*</varname></entry></row>
    <row><entry>&print-lines-var;</entry>
     <entry><varname>CUSTOM:*INSPECT-PRINT-LINES*</varname></entry></row>
 </tbody></tgroup></informaltable></para>

<para>User variable
 <firstterm><varname>CUSTOM:*INSPECT-LENGTH*</varname>
  <indexterm id="inspect-length" significance="preferred">
   <primary>*INSPECT-LENGTH*</primary></indexterm></firstterm>
 specifies the number of sequence elements or slots printed in detail
 when a sequence or a structure or a &clos; object is inspected.
</para></section>

<section id="time"><title>Macro &time;</title>

<para>The timing data printed by the macro &time; includes:<itemizedlist>
  <listitem><simpara>the real time (<quote>wall</quote> time,
    &get-internal-real-time;),</simpara></listitem>
  <listitem><simpara>the run time (processor time for this process,
    &get-internal-run-time;),</simpara></listitem>
  <listitem><simpara>the number of bytes allocated, and</simpara></listitem>
  <listitem><simpara>the number of &gc;ions performed, if any.
</simpara></listitem></itemizedlist></para>

<para>The macro <firstterm>&ts;
  <indexterm id="times" significance="preferred">
   <primary>TIMES</primary></indexterm></firstterm> (mnemonic:
 <quote><emphasis>TIME</emphasis> and <emphasis>S</emphasis>pace</quote>)
 is like the macro &time;: <code>(&ts; &form-r;)</code> evaluates the
 &form-r;, and, as a side effect, outputs detailed information about the
 memory allocations caused by this evaluation.  It also prints
 everything printed by &time;.</para>
</section>

<section id="ed"><title>Function &ed;</title>

<para>The function &ed; calls the external editor specified by the value of
 <code>(&getenv; "EDITOR")</code> or, failing that, the value of the variable
 <firstterm>&editor;<indexterm id="editor" significance="preferred">
   <primary>*EDITOR*</primary></indexterm></firstterm>
  (set in &config-lisp;).
 If the argument is a function name which was defined in the current
 session (not loaded from a file), the program text to be edited is a
 pretty-printed version (without comments) of the text which was used to
 define the function.</para>
</section>

<section id="apropos"><title>Functions &apropos; &amp; &apropos-list;</title>

<para>The search performed by &apropos; and &apropos-list; is
 case-insensitive.</para>

<formalpara><title>Variable &apropos-do-more;</title>
<para>You can make &apropos; print more information about the symbols it
 found by setting &apropos-do-more; to a list containing some of
 &function-k;, <constant>:VARIABLE</constant>, &type-k;, and &class-k;
 or just set it to &t; to get all of the values.</para></formalpara>

<formalpara><title>Variable &apropos-matcher;</title>
<para>You can make &apropos; and &apropos-list; be more flexible in
 their search by setting &apropos-matcher; to a &function-t; of one
 argument, a pattern (a &string-t;), returning a new &function-t; of one
 argument, a &symbol-t; name (also a &string-t;),
 which returns non-&nil; when the symbol name matches the pattern
 for the purposes of &apropos;.
 When &apropos-matcher; is &nil;, &search; is used.
 Some &module;s come with functions which can be used for
 &apropos-matcher;, e.g., &re-matcher;,
 <link linkend="fnmatch-matcher"><function>POSIX:FNMATCH-MATCHER</function></link>,
 <link linkend="pcre-matcher"><function>PCRE:PCRE-MATCHER</function></link>.
</para></formalpara>

</section>

<section id="dribble"><title>Function &dribble;</title>

<para>If &dribble; is called with an argument, and dribbling is already
 enabled, a warning is printed, and the new dribbling request is
 ignored.</para>

<para>Dribbling is implemented via a kind (but &not-e; a &recog-subt;)
 of &two-way-stream-t;, named &ds-t;.
 If you have a &source-r; &bidi-s; &x-r; and you want all transactions
 (input and output) on &x-r; to be copied to the &target-r; &out-s; &y-r;,
 you can do <programlisting id="dribble-example" language="lisp">
(&defvar; *loggable* &x-r;)
(&setq; &x-r; (&make-synonym-stream; '*loggable*))
(&defun; toggle-logging (&optional-amp; s)
  (&multiple-value-bind; (source target) (dribble-toggle *loggable* s)
    (&when; (&streamp; source) (&setq; *loggable* source))
    target))
(toggle-logging &y-r;)<lineannotation>start logging</lineannotation>
...
(toggle-logging)<lineannotation>finish logging</lineannotation>
...
(toggle-logging &y-r;)<lineannotation>restart logging</lineannotation>
...
(toggle-logging)<lineannotation>finish logging</lineannotation>
(&close; &y-r;)
</programlisting></para>

<variablelist>
 <varlistentry id="drist"><term><code>
    (<function>EXT:DRIBBLE-STREAM</function> &stream-r;)</code></term>
  <listitem><simpara>When &stream-r; is a &ds-t;, returns two values:
    the &source-r; and the &target-r; streams.  Otherwise returns &nil;.
 </simpara></listitem></varlistentry>
 <varlistentry id="drist-p"><term><code>
    (<function>EXT:DRIBBLE-STREAM-P</function> &stream-r;)</code></term>
  <listitem><simpara>When &stream-r; is a &ds-t;, returns &t;, otherwise
    returns &nil;.</simpara></listitem></varlistentry>
 <varlistentry id="drist-so"><term><code>
    (<function>EXT:DRIBBLE-STREAM-SOURCE</function> &stream-r;)</code></term>
  <listitem><simpara>When &stream-r; is a &ds-t;, returns its
    &source-r; stream, otherwise signals a &type-error-t;.
 </simpara></listitem></varlistentry>
 <varlistentry id="drist-ta"><term><code>
    (<function>EXT:DRIBBLE-STREAM-TARGET</function> &stream-r;)</code></term>
  <listitem><simpara>When &stream-r; is a &ds-t;, returns its
    &target-r; stream, otherwise signals a &type-error-t;.
 </simpara></listitem></varlistentry>
  <varlistentry id="mk-drist"><term><code>
     (<function>EXT:MAKE-DRIBBLE-STREAM</function>
     &source-r; &target-r;)</code></term>
   <listitem><simpara>Create a new &ds-t;.
 </simpara></listitem></varlistentry>
 <varlistentry id="dri-toggle"><term><code>
    (<function>EXT:DRIBBLE-TOGGLE</function> &stream-r;
    &optional-amp; &path-r;)</code></term>
  <listitem><simpara>When &stream-r; is a &ds-t; and &path-r; is &nil;,
    writes a dribble termination note to the &stream-r;'s &target-r;
    &stream-t; and returns &stream-r;'s &source-r; and &target-r;
    &stream-t;s;
    when &stream-r; is not a &ds-t; and &path-r; is non-&nil;,
    creates a new &ds-t;, dribbling from &stream-r; to &path-r;,
    writes a dribble initialization note to &path-r;,
    and return the &ds-t; (the second value is the &target-r; &stream-t;);
    otherwise &warn; that no appropriate action may be taken.
    &path-r; may be an open &out-s; or a &path-des;.
    See <link linkend="dribble-example">above</link> for the sample usage.
    See also <filename role="clisp-cvs">src/dribble.lisp</filename> in
    the &clisp; source tree.
</simpara></listitem></varlistentry></variablelist>

<section id="dribble-script"><title>Scripting and &dribble;</title>

<para>&dribble; works by operating on &terminal-io-var;,
 thus is does &not-e; work when &clisp; acts as a script interpreter
 (see <xref linkend="quickstart-unix"/>).</para>

<para>Traditionally, &cl; implementations set &standard-input-var;,
 &standard-output-var;, and &error-output-var; to a &synonym-stream-t;
 pointing to &terminal-io-var;, and &clisp; is no exception.
 Thus changing &terminal-io-var; to a dribble stream affects all
 standard i/o.</para>

<para>On the other hand, when &clisp; acts as a script interpreter, it
 adheres to the &unix; &stdio; <link linkend="script-exec">conventions</link>,
 thus &standard-input-var;, &standard-output-var;, and
 &error-output-var; are normal &file-stream-t;s,
 and thus are &not-e; affected by &dribble; (&terminal-io-var; - and
 thus <code>(&print; ... &t;)</code> - &is-e; still affected).
 The &ansi-cl; explicitly permits this behavior by stating
 <blockquote><para>&dribble; is intended primarily for interactive
   debugging; its effect cannot be relied upon when used in a program.
</para></blockquote></para>
</section></section>

</section>

<section id="environment-enq"><title>Environment Inquiry
  <ulink role="clhs" url="sec_25-1-3"/></title>

<section id="room"><title>Function &room;</title>

<para>The function <firstterm>&room;
  <indexterm id="room-func" significance="preferred">
   <primary>ROOM</primary></indexterm></firstterm>
  returns five values:<orderedlist>
  <listitem><simpara>space occupied by Lisp objects (in
    bytes)</simpara></listitem>
  <listitem><simpara>space available for allocating Lisp objects until
    the next &gc;ion is triggered (in bytes)</simpara></listitem>
  <listitem><simpara>space permanently allocated (in
    bytes)</simpara></listitem>
  <listitem><simpara>the number of times &gc;ion was done in this
    &clisp; session</simpara></listitem>
  <listitem><simpara>the cumulative space freed by all the &gc;ions in
    this &clisp; session (in bytes)</simpara></listitem>
  <listitem><simpara>the total time (in &internal-time-units-per-second;)
    spent collecting garbage</simpara></listitem></orderedlist></para>
</section>

<section id="gc-sect"><title>Function <firstterm><function>EXT:GC</function>
   <indexterm id="gc-func" significance="preferred">
    <primary>GC</primary></indexterm></firstterm></title>
<para>This function starts a global &gc;ion and returns the same values
 as &room;.</para>
<para>When the optional parameter is non-&nil; also invalidates
 just-in-time compiled objects.</para></section>

<section id="machine"><title>Machine</title>
<variablelist>
<varlistentry><term>&unix-only;</term>
 <listitem><simpara>The functions &short-site-name;, &long-site-name;
   should be defined in a site-specific &config-lisp; file.
   The default implementations try to read the value of the &env-var;
   <envar>ORGANIZATION</envar>, and, failing that,
   call <function role="unix">uname</function>.
</simpara></listitem></varlistentry>
<varlistentry><term>&win32-only;</term>
 <listitem><simpara>The functions &short-site-name;, &long-site-name;
   should be defined in a site-specific &config-lisp; file.
   The default implementations try to read the registry.
</simpara></listitem></varlistentry>
</variablelist>
</section>

<section id="version"><title>Function &lisp-implementation-version;</title>

<para>&lisp-implementation-version; returns
 the numeric version (like <literal>3.14</literal>), and
 the release date (like <literal>"1999-07-21"</literal>).
 When running on the same machine on which &clisp; was built, it appends
  the binary build and &mem-image; dump date in &uni-time;
  (like <literal>3141592654</literal>).
 When running on a different machine, it appends the &machine-instance;
  of the machine on which it was built.</para>
</section>

<section id="argv"><title>Function &argv;</title>
<para>This function will return a &fresh; &simple-vector-t; of
 &string-t; command line arguments passed to the runtime, including
 those already processed by &clisp;.
 Use &args; instead of this function to get the arguments for your program.
</para></section>

</section>

<section id="clock"><title>Time <ulink role="clhs" url="sec_25-1-4"/></title>

<!-- #if !(defined(UNIX) || defined(WIN32)) -->
<variablelist id="default-tz"><title>Default Time Zone</title>
<varlistentry><term>&no-platform-only;</term>
 <listitem><simpara>The variable <firstterm>&default-tz;</firstterm>
   contains the default time zone used by &encode-universal-time; and
   &decode-universal-time;.  It is initially set to -1
   (which means 1 hour east of Greenwich, i.e., Mid European Time).
</simpara></listitem></varlistentry></variablelist>
<!-- #endif -->

<para>The &TZ; in a &dec-time; does not necessarily have be an
 &integer-t;, but (as &float-t; or &rational-t; number)
 it should be a multiple of <literal role="data">1/3600</literal>.</para>

<table id="internal-time-units-table" frame="all">
 <title>Time granularity</title>
 <tgroup cols="3" colsep="1" rowsep="1" align="center">
 <thead><row><entry>platform</entry>
   <entry>&unix;</entry><entry>&win32;</entry></row></thead><tbody>
 <row><entry>&internal-time-units-per-second;</entry>
  <entry>1,000,000</entry><entry>10,000,000</entry></row>
</tbody></tgroup></table>

<para>&get-internal-run-time; returns the amount of run time
 consumed by the current &clisp; process since its startup.</para>

</section>

</chapter>


<chapter id="glossary"><title>Glossary
  <ulink role="clhs" url="chap-26"/></title>
<para>No notes.</para>
</chapter>

<chapter id="appendix"><title>Appendix
  <ulink role="clhs" url="chap-a"/></title>
<para>No notes.</para>
</chapter>
