0.8.6.1:
[sbcl.git] / doc / compiler.xml
diff --git a/doc/compiler.xml b/doc/compiler.xml
new file mode 100644 (file)
index 0000000..e0fde82
--- /dev/null
@@ -0,0 +1,942 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+               "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!ENTITY % myents SYSTEM "entities.inc">
+%myents;
+]>
+
+<chapter id="compiler"><title>The Compiler</title>
+
+<para>This chapter will discuss most compiler issues other than
+efficiency, including compiler error messages, the &SBCL; compiler's
+unusual approach to type safety in the presence of type declarations,
+the effects of various compiler optimization policies, and the way
+that inlining and open coding may cause optimized code to differ from
+a naive translation. Efficiency issues are sufficiently varied and
+separate that they have <link linkend="efficiency">their own
+chapter</link>.</para>
+
+<sect1 id="error-messages"><title>Error Messages</title>
+<!--INDEX {error messages}{compiler}-->
+<!--INDEX {compiler error messages}-->
+
+<para>The compiler supplies a large amount of source location
+information in error messages. The error messages contain a lot of
+detail in a terse format, so they may be confusing at first. Error
+messages will be illustrated using this example program:
+<programlisting>(defmacro zoq (x)
+`(roq (ploq (+ ,x 3))))
+
+(defun foo (y)
+(declare (symbol y))
+(zoq y))</programlisting>
+The main problem with this program is that it is trying to add
+<literal>3</literal> to a symbol. Note also that the functions
+<function>roq</function> and <function>ploq</function> aren't defined anywhere.
+</para>
+
+<sect2><title>The Parts of the Error Message</title>
+
+<para>When processing this program, the compiler will produce this
+warning: 
+
+<screen>file: /tmp/foo.lisp
+
+in: DEFUN FOO
+(ZOQ Y)
+--> ROQ PLOQ + 
+==>
+Y
+caught WARNING:
+Result is a SYMBOL, not a NUMBER.</screen>
+In this example we see each of the six possible parts of a compiler error
+message:
+<orderedlist>
+  <listitem><para><computeroutput>File: /tmp/foo.lisp</computeroutput>
+  This is the name of the file that the compiler read the relevant
+  code from.  The file name is displayed because it may not be
+  immediately obvious when there is an error during compilation of a
+  large system, especially when
+  <function>with-compilation-unit</function> is used to delay
+  undefined warnings.</para></listitem>
+  <listitem><para><computeroutput>in: DEFUN FOO</computeroutput> This is the
+  definition top level form responsible for the error. It is
+  obtained by taking the first two elements of the enclosing form
+  whose first element is a symbol beginning with <quote><literal>def</literal></quote>.
+  If there is no such enclosing <quote><literal>def</literal></quote> form, then the 
+  outermost form is used.  If there are multiple <literal>def</literal>
+  forms, then they are all printed from the outside in, separated by
+  <literal>=></literal>'s.  In this example, the problem was in the
+  <function>defun</function> for <function>foo</function>.</para></listitem>
+  <listitem><para><computeroutput>(ZOQ Y)</computeroutput> This is the
+  <emphasis>original source</emphasis> form responsible for the error.
+  Original source means that the form directly appeared in the
+  original input to the compiler, i.e. in the lambda passed to
+  <function>compile</function> or in the top level form read from the
+  source file. In this example, the expansion of the <function>zoq</function>
+  macro was responsible for the error.</para></listitem>
+  <listitem><para><computeroutput>--> ROQ PLOQ +</computeroutput> This is the
+  <emphasis>processing path</emphasis> that the compiler used to produce
+  the errorful code.  The processing path is a representation of
+  the evaluated forms enclosing the actual source that the
+  compiler encountered when processing the original source.
+  The path is the first element of each form, or the form itself
+  if the form is not a list.  These forms result from the
+  expansion of macros or source-to-source transformation done
+  by the compiler.  In this example, the enclosing evaluated forms
+  are the calls to <function>roq</function>, <function>ploq</function> and
+  <function>+</function>.  These calls resulted from the expansion of
+  the <function>zoq</function> macro.</para></listitem>
+  <listitem><para><computeroutput>==> Y</computeroutput> This is the
+  <emphasis>actual source</emphasis> responsible for the error. If
+  the actual source appears in the explanation, then
+  we print the next enclosing evaluated form, instead of
+  printing the actual source twice.  (This is the form
+  that would otherwise have been the last form of the processing
+  path.) In this example, the problem is with the evaluation of
+  the reference to the variable <varname>y</varname>.</para></listitem>
+  <listitem><para>
+  <computeroutput>caught WARNING: Result is a SYMBOL, not a NUMBER.</computeroutput>
+  This is the <emphasis>explanation</emphasis> of the problem. In this
+  example, the problem is that <varname>y</varname> evaluates to a symbol,
+  but is in a context where a number is required (the argument
+  to <function>+</function>).</para></listitem>
+</orderedlist>
+
+Note that each part of the error message is distinctively marked:
+
+<itemizedlist>
+  <listitem><para> <computeroutput>file:</computeroutput> and <computeroutput>in:</computeroutput>
+  mark the file and definition, respectively.</para></listitem>
+  <listitem><para> The original source is an indented form with no
+  prefix.</para></listitem>
+  <listitem><para> Each line of the processing path is prefixed with
+  <computeroutput>--></computeroutput></para></listitem>
+  <listitem><para> The actual source form is indented like the original
+  source, but is marked by a preceding <computeroutput>==></computeroutput> line.
+  </para></listitem>
+  <listitem><para> The explanation is prefixed with the error
+  severity, which can be <computeroutput>caught ERROR:</computeroutput>,
+  <computeroutput>caught WARNING:</computeroutput>,
+  <computeroutput>caught STYLE-WARNING:</computeroutput>, or
+  <computeroutput>note:</computeroutput>. </para></listitem>
+</itemizedlist>
+</para>
+
+<para>Each part of the error message is more specific than the preceding
+one.  If consecutive error messages are for nearby locations, then the
+front part of the error messages would be the same.  In this case, the
+compiler omits as much of the second message as in common with the
+first.  For example:
+<screen>file: /tmp/foo.lisp
+
+in: DEFUN FOO
+(ZOQ Y)
+--> ROQ
+==>
+(PLOQ (+ Y 3))
+caught STYLE-WARNING:
+undefined function: PLOQ
+
+==>
+(ROQ (PLOQ (+ Y 3)))
+caught STYLE-WARNING:
+undefined function: ROQ</screen>
+In this example, the file, definition and original source are
+identical for the two messages, so the compiler omits them in the
+second message.  If consecutive messages are entirely identical, then
+the compiler prints only the first message, followed by:
+<computeroutput>[Last message occurs <replaceable>repeats</replaceable> times]</computeroutput>
+where <replaceable>repeats</replaceable> is the number of times the message
+was given.</para>
+
+<para>If the source was not from a file, then no file line is printed.
+If the actual source is the same as the original source, then the
+processing path and actual source will be omitted. If no forms
+intervene between the original source and the actual source, then the
+processing path will also be omitted.</para>
+
+</sect2>
+
+<sect2><title>The Original and Actual Source</title>
+
+<para>The <emphasis>original source</emphasis> displayed will almost always be
+a list. If the actual source for an error message is a symbol, the
+original source will be the immediately enclosing evaluated list form.
+So even if the offending symbol does appear in the original source,
+the compiler will print the enclosing list and then print the symbol
+as the actual source (as though the symbol were introduced by a
+macro.)</para>
+
+<para>When the <emphasis>actual source</emphasis> is displayed
+(and is not a symbol), it will always
+be code that resulted from the expansion of a macro or a source-to-source
+compiler optimization.  This is code that did not appear in the original
+source program; it was introduced by the compiler.</para>
+
+<para>Keep in mind that when the compiler displays a source form
+in an error message, it always displays the most specific (innermost)
+responsible form.  For example, compiling this function
+<programlisting>(defun bar (x)
+(let (a)
+(declare (fixnum a))
+(setq a (foo x))
+a))</programlisting>
+gives this error message
+<screen>in: DEFUN BAR
+(LET (A) (DECLARE (FIXNUM A)) (SETQ A (FOO X)) A)
+caught WARNING: The binding of A is not a FIXNUM:
+NIL</screen>
+This error message is not saying <quote>there is a problem somewhere in
+this <function>let</function></quote> &mdash; it is saying that there is a
+problem with the <function>let</function> itself. In this example, the problem
+is that <varname>a</varname>'s <literal>nil</literal> initial value is not a
+<type>fixnum</type>.</para>
+
+</sect2>
+
+<sect2><title>The Processing Path</title>
+<!--INDEX processing path-->
+<!--INDEX macroexpansion-->
+<!--INDEX source-to-source transformation-->
+
+<para>The processing path is mainly useful for debugging macros, so if
+you don't write macros, you can probably ignore it. Consider this
+example:
+
+<programlisting>(defun foo (n)
+(dotimes (i n *undefined*)))
+</programlisting>
+
+Compiling results in this error message:
+
+<screen>in: DEFUN FOO
+(DOTIMES (I N *UNDEFINED*))
+--> DO BLOCK LET TAGBODY RETURN-FROM
+==>
+(PROGN *UNDEFINED*)
+caught STYLE-WARNING:
+undefined variable: *UNDEFINED*</screen>
+
+Note that <function>do</function> appears in the processing path. This is because
+<function>dotimes</function> expands into:
+
+<programlisting>(do ((i 0 (1+ i)) (#:g1 n))
+((>= i #:g1) *undefined*)
+(declare (type unsigned-byte i)))</programlisting>
+
+The rest of the processing path results from the expansion
+of <function>do</function>:
+
+<programlisting>
+  (block nil
+  (let ((i 0) (#:g1 n))
+  (declare (type unsigned-byte i))
+  (tagbody (go #:g3)
+  #:g2    (psetq i (1+ i))
+  #:g3    (unless (>= i #:g1) (go #:g2))
+  (return-from nil (progn *undefined*)))))
+</programlisting>
+
+In this example, the compiler descended into the <function>block</function>,
+<function>let</function>, <function>tagbody</function> and <function>return-from</function> to
+reach the <function>progn</function> printed as the actual source. This is a
+place where the <quote>actual source appears in explanation</quote> rule
+was applied. The innermost actual source form was the symbol
+<varname>*undefined*</varname> itself, but that also appeared in the
+explanation, so the compiler backed out one level.</para>
+
+</sect2>
+
+<sect2><title>Error Severity</title>
+<!--INDEX severity of compiler errors -->
+<!--INDEX compiler error severity -->
+
+<para>There are four levels of compiler error severity:
+<wordasword>error</wordasword>, <wordasword>warning</wordasword>, <wordasword>style
+warning</wordasword>, and <wordasword>note</wordasword>. The first three levels correspond
+to condition classes which are defined in the &ANSI; standard for
+&CommonLisp; and which have special significance to the
+<function>compile</function> and <function>compile-file</function> functions. These
+levels of compiler error severity occur when the compiler handles
+conditions of these classes. The fourth level of compiler error
+severity, <wordasword>note</wordasword>, is used for problems which are too mild
+for the standard condition classes, typically hints about how
+efficiency might be improved.</para>
+
+</sect2>
+
+<sect2><title>Errors During Macroexpansion</title>
+<!--INDEX {macroexpansion}{errors during}-->
+
+<para>The compiler handles errors that happen during macroexpansion,
+turning them into compiler errors. If you want to debug the error (to
+debug a macro), you can set <varname>*break-on-signals*</varname> to
+<literal>error</literal>. For example, this definition:
+
+<programlisting>(defun foo (e l)
+(do ((current l (cdr current))
+((atom current) nil))
+(when (eq (car current) e) (return current))))</programlisting>
+
+gives this error:
+
+<screen>in: DEFUN FOO
+(DO ((CURRENT L #) (# NIL)) (WHEN (EQ # E) (RETURN CURRENT)) )
+caught ERROR: 
+(in macroexpansion of (DO # #))
+(hint: For more precise location, try *BREAK-ON-SIGNALS*.)
+DO step variable is not a symbol: (ATOM CURRENT)</screen>
+</para>
+
+</sect2>
+
+<sect2><title>Read Errors</title>
+<!--INDEX {read errors}{compiler}-->
+
+<para>&SBCL;'s compiler (unlike &CMUCL;'s) does not attempt to recover
+from read errors when reading a source file, but instead just reports
+the offending character position and gives up on the entire source
+file.</para>
+
+</sect2>
+
+<!-- FIXME: How much control over error messages is in SBCL?
+     _     How much should be? How much of this documentation should
+     _     we save or adapt? 
+     _ 
+     _ %%\node Error Message Parameterization,  , Read Errors, Interpreting Error Messages
+     _ \subsection{Error Message Parameterization}
+     _ \cpsubindex{error messages}{verbosity}
+     _ \cpsubindex{verbosity}{of error messages}
+     _ 
+     _ There is some control over the verbosity of error messages.  See also
+     _ \varref{undefined-warning-limit}, \code{*efficiency-note-limit*} and
+     _ \varref{efficiency-note-cost-threshold}.
+     _ 
+     _ \begin{defvar}{}{enclosing-source-cutoff}
+     _ 
+     _   This variable specifies the number of enclosing actual source forms
+     _   that are printed in full, rather than in the abbreviated processing
+     _   path format.  Increasing the value from its default of \code{1}
+     _   allows you to see more of the guts of the macroexpanded source,
+     _   which is useful when debugging macros.
+     _ \end{defvar}
+     _ 
+     _ \begin{defvar}{}{error-print-length}
+     _   \defvarx{error-print-level}
+     _ 
+     _   These variables are the print level and print length used in
+     _   printing error messages.  The default values are \code{5} and
+     _   \code{3}.  If null, the global values of \code{*print-level*} and
+     _   \code{*print-length*} are used.
+     _ \end{defvar}
+     _ 
+     _ \begin{defmac}{extensions:}{define-source-context}{%
+     _     \args{\var{name} \var{lambda-list} \mstar{form}}}
+     _ 
+     _   This macro defines how to extract an abbreviated source context from
+     _   the \var{name}d form when it appears in the compiler input.
+     _   \var{lambda-list} is a \code{defmacro} style lambda-list used to
+     _   parse the arguments.  The \var{body} should return a list of
+     _   subforms that can be printed on about one line.  There are
+     _   predefined methods for \code{defstruct}, \code{defmethod}, etc.  If
+     _   no method is defined, then the first two subforms are returned.
+     _   Note that this facility implicitly determines the string name
+     _   associated with anonymous functions.
+     _ \end{defmac}
+     _ 
+     _ -->
+
+</sect1>
+
+<sect1 id="compiler-types"><title>The Compiler's Handling of Types</title>
+
+<para>The most unusual features of the &SBCL; compiler (which is
+very similar to the original &CMUCL; compiler, also known as
+&Python;) is its unusually sophisticated understanding of the
+&CommonLisp; type system and its unusually conservative approach to
+the implementation of type declarations. These two features reward the
+use of type declarations throughout development, even when high
+performance is not a concern. (Also, as discussed <link
+linkend="efficiency">in the chapter on performance</link>, the use of
+appropriate type declarations can be very important for performance as
+well.)</para>
+
+<para>The &SBCL; compiler, like the related compiler in &CMUCL;,
+treats type declarations much differently than other Lisp compilers.
+By default (<emphasis>i.e.</emphasis>, at ordinary levels of the
+<parameter>safety</parameter> compiler optimization parameter), the compiler
+doesn't blindly believe most type declarations; it considers them
+assertions about the program that should be checked.</para>
+
+<para>The &SBCL; compiler also has a greater knowledge of the
+&CommonLisp; type system than other compilers.  Support is incomplete
+only for the <type>not</type>, <type>and</type> and <type>satisfies</type>
+types.
+<!-- FIXME: See also sections \ref{advanced-type-stuff}
+     and \ref{type-inference}, once we snarf them from the
+     CMU CL manual. -->
+</para>
+
+<sect2 id="compiler-impl-limitations"><title>Implementation Limitations</title>
+
+<para>
+  Ideally, the compiler would consider <emphasis>all</emphasis> type declarations to
+  be assertions, so that adding type declarations to a program, no
+  matter how incorrect they might be, would <emphasis>never</emphasis> cause
+  undefined behavior. As of &SBCL; version 0.8.1, the compiler is known to
+  fall short of this goal in two areas:
+  <itemizedlist>
+    <listitem><para><function>Proclaim</function>ed constraints on argument and
+    result types of a function are supposed to be checked by the
+    function. If the function type is proclaimed before function
+    definition, type checks are inserted by the compiler, but the
+    standard allows the reversed order, in which case the compiler
+    will trust the declaration.</para></listitem>
+    <listitem><para>The compiler cannot check types of an unknown number
+    of values; if the number of generated values is unknown, but the
+    number of consumed is known, only consumed values are
+    checked.</para></listitem>
+    <listitem><para>There are a few poorly characterized but apparently
+    very uncommon situations where a type declaration in an unexpected
+    location will be trusted and never checked by the
+    compiler.</para></listitem>
+</itemizedlist></para>
+
+<para>These are important bugs, but are not necessarily easy to fix,
+so they may, alas, remain in the system for a while.</para>
+
+</sect2>
+
+<sect2><title>Type Errors at Compile Time</title>
+<!--INDEX compile time type errors-->
+<!--INDEX type checking}{at compile time}-->
+
+<para>If the compiler can prove at compile time that some portion of
+the program cannot be executed without a type error, then it will give
+a warning at compile time. It is possible that the offending code
+would never actually be executed at run-time due to some higher level
+consistency constraint unknown to the compiler, so a type warning
+doesn't always indicate an incorrect program. For example, consider
+this code fragment:
+
+<programlisting>(defun raz (foo)
+(let ((x (case foo
+(:this 13)
+(:that 9)
+(:the-other 42))))
+(declare (fixnum x))
+(foo x)))
+</programlisting>
+
+Compilation produces this warning:
+
+<screen>in: DEFUN RAZ
+(CASE FOO (:THIS 13) (:THAT 9) (:THE-OTHER 42))
+--> LET COND IF COND IF COND IF
+==>
+(COND)
+caught WARNING: This is not a FIXNUM:
+NIL</screen>
+
+In this case, the warning means that if <varname>foo</varname> isn't any of
+<literal>:this</literal>, <literal>:that</literal> or <literal>:the-other</literal>, then
+<varname>x</varname> will be initialized to <literal>nil</literal>, which the
+<type>fixnum</type> declaration makes illegal. The warning will go away if
+<function>ecase</function> is used instead of <function>case</function>, or if
+<literal>:the-other</literal> is changed to <literal>t</literal>.</para>
+
+<para>This sort of spurious type warning happens moderately often in
+the expansion of complex macros and in inline functions. In such
+cases, there may be dead code that is impossible to correctly execute.
+The compiler can't always prove this code is dead (could never be
+executed), so it compiles the erroneous code (which will always signal
+an error if it is executed) and gives a warning.</para>
+
+<para>
+  Type warnings are inhibited when the
+  <parameter>sb-ext:inhibit-warnings</parameter> optimization quality is
+  <literal>3</literal>. (See <link linkend="compiler-policy">the section
+  on compiler policy</link>.) This can be used in a local declaration
+  to inhibit type warnings in a code fragment that has spurious
+warnings.</para>
+
+</sect2>
+
+<sect2 id="precisetypechecking"><title>Precise Type Checking</title>
+<!--INDEX precise type checking-->
+<!--INDEX {type checking}{precise}-->
+
+<para>With the default compilation policy, all type declarations are
+precisely checked, except in a few situations where they are simply
+ignored instead. Precise checking means that the check is done as
+though <function>typep</function> had been called with the exact type
+specifier that appeared in the declaration. In &SBCL;, adding type
+declarations makes code safer. (Except that as noted <link
+linkend="compiler-impl-limitations">elsewhere</link>, remaining bugs
+in the compiler's handling of types unfortunately provide some
+exceptions to this rule.)</para>
+
+<para>If a variable is declared to be
+<type>(integer 3 17)</type> then its value must always be an integer
+between <literal>3</literal> and <literal>17</literal>. If multiple type
+declarations apply to a single variable, then all the declarations
+must be correct; it is as though all the types were intersected
+producing a single <type>and</type> type specifier.</para>
+
+<para>Argument and result type declarations are automatically
+enforced. If you declare the type of a function argument, a type check
+will be done when that function is called. In a function call, the
+called function does the argument type checking.</para>
+
+<para>The types of structure slots are also checked. The value of a
+structure slot must always be of the type indicated in any
+<literal>:type</literal> slot option. </para>
+
+<para>In traditional &CommonLisp; compilers, not all type assertions
+are checked, and type checks are not precise. Traditional compilers
+blindly trust explicit type declarations, but may check the argument
+type assertions for built-in functions. Type checking is not precise,
+since the argument type checks will be for the most general type legal
+for that argument. In many systems, type declarations suppress what
+little type checking is being done, so adding type declarations makes
+code unsafe. This is a problem since it discourages writing type
+declarations during initial coding. In addition to being more error
+prone, adding type declarations during tuning also loses all the
+benefits of debugging with checked type assertions.</para>
+
+<para>To gain maximum benefit from the compiler's type checking, you
+should always declare the types of function arguments and structure
+slots as precisely as possible. This often involves the use of
+<type>or</type>, <type>member</type>, and other list-style type specifiers.</para>
+
+</sect2>
+
+<sect2 id="weakened-type-checking"><title>Weakened Type Checking</title>
+<!--INDEX weakened type checking-->
+<!--INDEX {type checking}{weakened}-->
+
+<para>At one time, &CMUCL; supported another level of type checking,
+<quote>weakened type checking</quote>, when the value for the
+<parameter>speed</parameter> optimization quality is greater than
+<parameter>safety</parameter>, and <parameter>safety</parameter> is not <literal>0</literal>.
+The &CMUCL; manual still has a description of it, but even the CMU CL
+code no longer corresponds to the manual. Some of this partial safety
+checking lingers on in SBCL, but it's not a supported feature, and 
+should not be relied on. If you ask the compiler to optimize
+<parameter>speed</parameter> to a higher level than <parameter>safety</parameter>,
+your program is performing without a safety net, because &SBCL; may
+at its option believe any or all type declarations with either partial
+or nonexistent runtime checking.</para>
+
+</sect2>
+
+<sect2><title>Getting Existing Programs to Run</title>
+<!--INDEX {existing programs}{to run}-->
+<!--INDEX {types}{portability}-->
+<!--INDEX {compatibility with other Lisps}
+     (should also have an entry in the non-&ANSI;-isms section)-->
+
+<para>Since &SBCL;'s compiler, like &CMUCL;'s compiler, does much more
+comprehensive type checking than most Lisp compilers, &SBCL; may
+detect type errors in programs that have been debugged using other
+compilers. These errors are mostly incorrect declarations, although
+compile-time type errors can find actual bugs if parts of the program
+have never been tested.</para>
+
+<para>Some incorrect declarations can only be detected by run-time
+type checking. It is very important to initially compile a program
+with full type checks (high <parameter>safety</parameter> optimization) and
+then test this safe version. After the checking version has been
+tested, then you can consider weakening or eliminating type checks.
+<emphasis>This applies even to previously debugged
+programs,</emphasis> because the &SBCL; compiler does much more type
+inference than other &CommonLisp; compilers, so an incorrect
+declaration can do more damage.</para>
+
+<para>The most common problem is with variables whose constant initial
+value doesn't match the type declaration. Incorrect constant initial
+values will always be flagged by a compile-time type error, and they
+are simple to fix once located. Consider this code fragment:
+
+<programlisting>(prog (foo)
+(declare (fixnum foo))
+(setq foo ...)
+...)</programlisting>
+
+Here <varname>foo</varname> is given an initial value of <literal>nil</literal>, but
+is declared to be a <type>fixnum</type>.  Even if it is never read, the
+initial value of a variable must match the declared type.  There are
+two ways to fix this problem. Change the declaration
+
+<programlisting>(prog (foo)
+(declare (type (or fixnum null) foo))
+(setq foo ...)
+...)</programlisting>
+
+or change the initial value
+
+<programlisting>(prog ((foo 0))
+(declare (fixnum foo))
+(setq foo ...)
+...)</programlisting>
+
+It is generally preferable to change to a legal initial value rather
+than to weaken the declaration, but sometimes it is simpler to weaken
+the declaration than to try to make an initial value of the
+appropriate type.</para>
+
+<para>Another declaration problem occasionally encountered is
+incorrect declarations on <function>defmacro</function> arguments. This can happen
+when a function is converted into a macro. Consider this macro:
+
+<programlisting>(defmacro my-1+ (x)
+(declare (fixnum x))
+`(the fixnum (1+ ,x)))</programlisting>
+
+Although legal and well-defined &CommonLisp; code, this meaning of
+this definition is almost certainly not what the writer intended. For
+example, this call is illegal:
+
+<programlisting>(my-1+ (+ 4 5))</programlisting>
+
+This call is illegal because the argument to the macro is
+<literal>(+ 4 5)</literal>, which is a <type>list</type>, not a
+<type>fixnum</type>.  Because of
+macro semantics, it is hardly ever useful to declare the types of
+macro arguments.  If you really want to assert something about the
+type of the result of evaluating a macro argument, then put a
+<function>the</function> in the expansion:
+
+<programlisting>(defmacro my-1+ (x)
+`(the fixnum (1+ (the fixnum ,x))))</programlisting>
+
+In this case, it would be stylistically preferable to change this
+macro back to a function and declare it inline. 
+<!--FIXME: <xref>inline-expansion, once we crib the 
+     relevant text from the CMU CL manual.-->
+</para>
+
+<para>
+  Some more subtle problems are caused by incorrect declarations that
+  can't be detected at compile time.  Consider this code:
+
+  <programlisting>(do ((pos 0 (position #\a string :start (1+ pos))))
+  ((null pos))
+  (declare (fixnum pos))
+  ...)</programlisting>
+
+  Although <varname>pos</varname> is almost always a <varname>fixnum</varname>, it is
+  <literal>nil</literal> at the end of the loop. If this example is compiled
+  with full type checks (the default), then running it will signal a
+  type error at the end of the loop. If compiled without type checks,
+  the program will go into an infinite loop (or perhaps
+  <function>position</function> will complain because <literal>(1+ nil)</literal> isn't
+  a sensible start.) Why? Because if you compile without type checks,
+  the compiler just quietly believes the type declaration. Since the
+  compiler believes that <varname>pos</varname> is always a <type>fixnum</type>, it
+  believes that <varname>pos</varname> is never <literal>nil</literal>, so
+  <literal>(null pos)</literal> is never true, and the loop exit test is
+  optimized away. Such errors are sometimes flagged by unreachable code
+  notes, but it is still important to initially compile and test any
+  system with full type checks, even if the system works fine when
+compiled using other compilers.</para>
+
+<para>In this case, the fix is to weaken the type declaration to
+<type>(or fixnum null)</type>.
+<footnote><para>Actually, this declaration is 
+unnecessary in &SBCL;, since it already knows that <function>position</function>
+returns a non-negative <type>fixnum</type> or <literal>nil</literal>.
+</para></footnote>
+
+Note that there is usually little performance penalty for weakening a
+declaration in this way. Any numeric operations in the body can still
+assume that the variable is a <type>fixnum</type>, since <literal>nil</literal>
+is not a legal numeric argument. Another possible fix would be to say:
+
+<programlisting>(do ((pos 0 (position #\a string :start (1+ pos))))
+((null pos))
+(let ((pos pos))
+(declare (fixnum pos))
+...))</programlisting>
+
+This would be preferable in some circumstances, since it would allow a
+non-standard representation to be used for the local <varname>pos</varname>
+variable in the loop body.
+<!-- FIXME: <xref>ND-variables, once we crib the text from the 
+     CMU CL manual. -->
+</para>
+
+</sect2>
+
+</sect1>
+
+<sect1 id="compiler-policy"><title>Compiler Policy</title>
+
+<para>As of version 0.6.4, &SBCL; still uses most of the &CMUCL; code
+for compiler policy. The &CMUCL; code has many features and high-quality
+documentation, but the two unfortunately do not match. So this area of
+the compiler and its interface needs to be cleaned up. Meanwhile, here
+is some rudimentary documentation on the current behavior of the
+system.</para>
+
+<para>Compiler policy is controlled by the <parameter>optimize</parameter>
+declaration. The compiler supports the &ANSI; optimization qualities,
+and also an extension <parameter>sb-ext:inhibit-warnings</parameter>.</para>
+
+<para>Ordinarily, when the <parameter>speed</parameter> quality is high, the
+compiler emits notes to notify the programmer about its inability to
+apply various optimizations. Setting
+<parameter>sb-ext:inhibit-warnings</parameter> to a value at least as large as
+the <parameter>speed</parameter> quality inhibits this notification. This can
+be useful to suppress notes about code which is known to be
+unavoidably inefficient. (For example, the compiler issues notes about
+having to use generic arithmetic instead of fixnum arithmetic, which
+is not helpful for code which by design supports arbitrary-sized
+integers instead of being limited to fixnums.)</para>
+
+<note><para>The basic functionality of the <parameter>optimize
+inhibit-warnings</parameter> extension will probably be supported in all future
+versions of the system, but it will probably be renamed when the
+compiler and its interface are cleaned up. The current name is
+misleading, because it mostly inhibits optimization notes, not
+warnings. And making it an optimization quality is misleading, because
+it shouldn't affect the resulting code at all. It may become a
+declaration identifier with a name like
+<parameter>sb-ext:inhibit-notes</parameter>, so that what's currently written
+
+<programlisting>(declaim (optimize (sb-ext:inhibit-warnings 2)))</programlisting>
+
+would become something like
+
+<programlisting>(declaim (sb-ext:inhibit-notes 2))</programlisting>
+
+</para></note>
+
+<para> (In early versions of SBCL, a <parameter>speed</parameter> value of zero
+was used to enable byte compilation, but since version 0.7.0, SBCL
+only supports native compilation.)</para>
+
+<para>When <parameter>safety</parameter> is zero, almost all runtime checking
+of types, array bounds, and so forth is suppressed.</para>
+
+<para>When <parameter>safety</parameter> is less than <parameter>speed</parameter>, any
+and all type checks may be suppressed. At some point in the past,
+&CMUCL; had <link linkend="weakened-type-checking">a more nuanced
+interpretation of this</link>. However, &SBCL; doesn't support that
+interpretation, and setting <parameter>safety</parameter> less than
+<parameter>speed</parameter> may have roughly the same effect as setting
+<parameter>safety</parameter> to zero.</para>
+
+<para>The value of <parameter>space</parameter> mostly influences the
+compiler's decision whether to inline operations, which tend to
+increase the size of programs. Use the value <literal>0</literal> with
+caution, since it can cause the compiler to inline operations so
+indiscriminately that the net effect is to slow the program by causing
+cache misses or swapping.</para>
+
+<!-- FIXME: old CMU CL compiler policy, should perhaps be adapted
+     _    for SBCL. (Unfortunately, the CMU CL docs are out of sync with the
+     _    CMU CL code, so adapting this requires not only reformatting
+     _    the documentation, but rooting out code rot.)
+     _
+     _<sect2 id="compiler-policy"><title>Compiler Policy</1000
+     _  INDEX {policy}{compiler}
+     _  INDEX compiler policy
+     _
+     _<para>The policy is what tells the compiler <emphasis>how</emphasis> to
+     _compile a program. This is logically (and often textually) distinct
+     _from the program itself. Broad control of policy is provided by the
+     _<parameter>optimize</parameter> declaration; other declarations and variables
+     _control more specific aspects of compilation.</para>
+     _
+     _\begin{comment}
+     _* The Optimize Declaration::
+     _* The Optimize-Interface Declaration::
+     _\end{comment}
+     _
+     _%%\node The Optimize Declaration, The Optimize-Interface Declaration, Compiler Policy, Compiler Policy
+     _\subsection{The Optimize Declaration}
+     _\label{optimize-declaration}
+     _\cindex{optimize declaration}
+     _\cpsubindex{declarations}{\code{optimize}}
+     _
+     _The \code{optimize} declaration recognizes six different
+     _\var{qualities}.  The qualities are conceptually independent aspects
+     _of program performance.  In reality, increasing one quality tends to
+     _have adverse effects on other qualities.  The compiler compares the
+     _relative values of qualities when it needs to make a trade-off; i.e.,
+     _if \code{speed} is greater than \code{safety}, then improve speed at
+     _the cost of safety.
+     _
+     _The default for all qualities (except \code{debug}) is \code{1}.
+     _Whenever qualities are equal, ties are broken according to a broad
+     _idea of what a good default environment is supposed to be.  Generally
+     _this downplays \code{speed}, \code{compile-speed} and \code{space} in
+     _favor of \code{safety} and \code{debug}.  Novice and casual users
+     _should stick to the default policy.  Advanced users often want to
+     _improve speed and memory usage at the cost of safety and
+     _debuggability.
+     _
+     _If the value for a quality is \code{0} or \code{3}, then it may have a
+     _special interpretation.  A value of \code{0} means ``totally
+     _unimportant'', and a \code{3} means ``ultimately important.''  These
+     _extreme optimization values enable ``heroic'' compilation strategies
+     _that are not always desirable and sometimes self-defeating.
+     _Specifying more than one quality as \code{3} is not desirable, since
+     _it doesn't tell the compiler which quality is most important.
+     _
+     _
+     _These are the optimization qualities:
+     _\begin{Lentry}
+     _
+     _\item[\code{speed}] \cindex{speed optimization quality}How fast the
+     _  program should is run.  \code{speed 3} enables some optimizations
+     _  that hurt debuggability.
+     _
+     _\item[\code{compilation-speed}] \cindex{compilation-speed optimization
+     _    quality}How fast the compiler should run.  Note that increasing
+     _  this above \code{safety} weakens type checking.
+     _
+     _\item[\code{space}] \cindex{space optimization quality}How much space
+     _  the compiled code should take up.  Inline expansion is mostly
+     _  inhibited when \code{space} is greater than \code{speed}.  A value
+     _  of \code{0} enables indiscriminate inline expansion.  Wide use of a
+     _  \code{0} value is not recommended, as it may waste so much space
+     _  that run time is slowed.  \xlref{inline-expansion} for a discussion
+     _  of inline expansion.
+     _
+     _\item[\code{debug}] \cindex{debug optimization quality}How debuggable
+     _  the program should be.  The quality is treated differently from the
+     _  other qualities: each value indicates a particular level of debugger
+     _  information; it is not compared with the other qualities.
+     _  \xlref{debugger-policy} for more details.
+     _
+     _\item[\code{safety}] \cindex{safety optimization quality}How much
+     _  error checking should be done.  If \code{speed}, \code{space} or
+     _  \code{compilation-speed} is more important than \code{safety}, then
+     _  type checking is weakened (\pxlref{weakened-type-checks}).  If
+     _  \code{safety} if \code{0}, then no run time error checking is done.
+     _  In addition to suppressing type checks, \code{0} also suppresses
+     _  argument count checking, unbound-symbol checking and array bounds
+     _  checks.
+     _
+     _\item[\code{extensions:inhibit-warnings}] \cindex{inhibit-warnings
+     _    optimization quality}This is a CMU extension that determines how
+     _  little (or how much) diagnostic output should be printed during
+     _  compilation.  This quality is compared to other qualities to
+     _  determine whether to print style notes and warnings concerning those
+     _  qualities.  If \code{speed} is greater than \code{inhibit-warnings},
+     _  then notes about how to improve speed will be printed, etc.  The
+     _  default value is \code{1}, so raising the value for any standard
+     _  quality above its default enables notes for that quality.  If
+     _  \code{inhibit-warnings} is \code{3}, then all notes and most
+     _  non-serious warnings are inhibited.  This is useful with
+     _  \code{declare} to suppress warnings about unavoidable problems.
+     _\end{Lentry}
+     _
+     _%%\node The Optimize-Interface Declaration,  , The Optimize Declaration, Compiler Policy
+     _\subsection{The Optimize-Interface Declaration}
+     _\label{optimize-interface-declaration}
+     _\cindex{optimize-interface declaration}
+     _\cpsubindex{declarations}{\code{optimize-interface}}
+     _
+     _The \code{extensions:optimize-interface} declaration is identical in
+     _syntax to the \code{optimize} declaration, but it specifies the policy
+     _used during compilation of code the compiler automatically generates
+     _to check the number and type of arguments supplied to a function.  It
+     _is useful to specify this policy separately, since even thoroughly
+     _debugged functions are vulnerable to being passed the wrong arguments.
+     _The \code{optimize-interface} declaration can specify that arguments
+     _should be checked even when the general \code{optimize} policy is
+     _unsafe.
+     _
+     _Note that this argument checking is the checking of user-supplied
+     _arguments to any functions defined within the scope of the
+     _declaration, \code{not} the checking of arguments to \llisp{}
+     _primitives that appear in those definitions.
+     _
+     _The idea behind this declaration is that it allows the definition of
+     _functions that appear fully safe to other callers, but that do no
+     _internal error checking.  Of course, it is possible that arguments may
+     _be invalid in ways other than having incorrect type.  Functions
+     _compiled unsafely must still protect themselves against things like
+     _user-supplied array indices that are out of bounds and improper lists.
+     _See also the \kwd{context-declarations} option to
+     _\macref{with-compilation-unit}.
+     _
+     _(end of section on compiler policy)
+     _-->
+
+</sect1>
+
+<sect1 id="open-coding"><title>Open Coding and Inline Expansion</title>
+<!--INDEX open-coding-->
+<!--INDEX inline expansion-->
+<!--INDEX static functions-->
+
+<para>Since &CommonLisp; forbids the redefinition of standard
+functions, the compiler can have special knowledge of these standard
+functions embedded in it. This special knowledge is used in various
+ways (open coding, inline expansion, source transformation), but the
+implications to the user are basically the same:
+<itemizedlist>
+  <listitem><para> Attempts to redefine standard functions may
+  be frustrated, since the function may never be called. Although
+  it is technically illegal to redefine standard functions, users
+  sometimes want to implicitly redefine these functions when they
+  are debugging using the <function>trace</function> macro.  Special-casing
+  of standard functions can be inhibited using the
+  <parameter>notinline</parameter> declaration.</para></listitem>
+  <listitem><para> The compiler can have multiple alternate
+  implementations of standard functions that implement different
+  trade-offs of speed, space and safety.  This selection is
+  based on the <link linkend="compiler-policy">compiler policy</link>.
+  </para></listitem>
+</itemizedlist>
+</para>
+
+<para>When a function call is <emphasis>open coded</emphasis>, inline code whose
+effect is equivalent to the function call is substituted for that
+function call. When a function call is <emphasis>closed coded</emphasis>, it
+is usually left as is, although it might be turned into a call to a
+different function with different arguments. As an example, if
+<function>nthcdr</function> were to be open coded, then
+
+<programlisting>(nthcdr 4 foobar)</programlisting>
+
+might turn into
+
+<programlisting>(cdr (cdr (cdr (cdr foobar))))</programlisting>
+
+or even
+
+<programlisting>(do ((i 0 (1+ i))
+(list foobar (cdr foobar)))
+((= i 4) list))</programlisting>
+
+If <function>nth</function> is closed coded, then
+
+<programlisting>
+  (nth x l)
+</programlisting>
+
+might stay the same, or turn into something like
+
+<programlisting>
+  (car (nthcdr x l))
+</programlisting>
+</para>
+
+<para>In general, open coding sacrifices space for speed, but some
+functions (such as <function>car</function>) are so simple that they are always
+open-coded. Even when not open-coded, a call to a standard function
+may be transformed into a different function call (as in the last
+example) or compiled as <emphasis>static call</emphasis>. Static function call
+uses a more efficient calling convention that forbids
+redefinition.</para>
+
+</sect1>
+
+</chapter>