gencgc: code_page_p() must die!
[sbcl.git] / doc / manual / compiler.texinfo
index cd0c1cf..5fa6525 100644 (file)
-@node  The Compiler, The Debugger, Introduction, Top
+@node Compiler
 @comment  node-name,  next,  previous,  up
-@chapter The Compiler
-
-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
+@chapter Compiler
+
+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 their own chapter, @ref{Efficiency}.
 
 @menu
-* Error Messages::              
+* Diagnostic Messages::
 * Handling of Types::           
 * Compiler Policy::             
+* Compiler Errors::             
 * Open Coding and Inline Expansion::  
+* Interpreter::
 @end menu
 
-@node  Error Messages, Handling of Types, The Compiler, The Compiler
+@node  Diagnostic Messages
 @comment  node-name,  next,  previous,  up
-@section Error Messages
-@cindex Error messages, Compiler
-@cindex Compiler error messages
+@section Diagnostic Messages
+@cindex Messages, Compiler
+@cindex Compiler messages
 
-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
+@menu
+* Controlling Verbosity::       
+* Diagnostic Severity::         
+* Understanding Compiler Diagnostics::  
+@end menu
+
+@node Controlling Verbosity
+@comment  node-name,  next,  previous,  up
+@subsection Controlling Verbosity
+
+The compiler can be quite verbose in its diagnostic reporting, rather
+more then some users would prefer -- the amount of noise emitted can
+be controlled, however.
+
+To control emission of compiler diagnostics (of any severity other
+than @code{error}: @pxref{Diagnostic Severity}) use the
+@code{sb-ext:muffle-conditions} and @code{sb-ext:unmuffle-conditions}
+declarations, specifying the type of condition that is to be muffled
+(the muffling is done using an associated @code{muffle-warning} restart).
+
+Global control:
+@lisp
+;;; Muffle compiler-notes globally
+(declaim (sb-ext:muffle-conditions sb-ext:compiler-note))
+@end lisp
+
+Local control:
+@lisp
+;;; Muffle compiler-notes based on lexical scope
+(defun foo (x)
+  (declare (optimize speed) (fixnum x)
+           (sb-ext:muffle-conditions sb-ext:compiler-note))
+  (values (* x 5) ; no compiler note from this
+    (locally
+      (declare (sb-ext:unmuffle-conditions sb-ext:compiler-note))
+      ;; this one gives a compiler note
+      (* x -5))))
+@end lisp
+
+@deffn {Declaration} @sbext{muffle-conditions}
+Syntax: type*
+
+Muffles the diagnostic messages that would be caused by compile-time
+signals of given types.
+@end deffn
+
+@deffn {Declaration} @sbext{unmuffle-conditions}
+Syntax: type*
+
+Cancels the effect of a previous @code{sb-ext:muffle-conditions}
+declaration.
+@end deffn
+
+Various details of @emph{how} the compiler messages are printed can be
+controlled via the alist
+@code{sb-ext:*compiler-print-variable-alist*}.
+
+@include var-sb-ext-star-compiler-print-variable-alist-star.texinfo
+
+For information about muffling warnings signaled outside of the
+compiler, see @ref{Customization Hooks for Users}.
+
+@c <!-- FIXME: How much control over error messages is in SBCL?
+@c      _     How much should be? How much of this documentation should
+@c      _     we save or adapt? 
+@c      _ 
+@c      _ %%\node Error Message Parameterization,  , Read Errors, Interpreting Error Messages
+@c      _ \subsection{Error Message Parameterization}
+@c      _ \cpsubindex{error messages}{verbosity}
+@c      _ \cpsubindex{verbosity}{of error messages}
+@c      _ 
+@c      _ There is some control over the verbosity of error messages.  See also
+@c      _ \varref{undefined-warning-limit}, \code{*efficiency-note-limit*} and
+@c      _ \varref{efficiency-note-cost-threshold}.
+@c      _ 
+@c      _ \begin{defvar}{}{enclosing-source-cutoff}
+@c      _ 
+@c      _   This variable specifies the number of enclosing actual source forms
+@c      _   that are printed in full, rather than in the abbreviated processing
+@c      _   path format.  Increasing the value from its default of \code{1}
+@c      _   allows you to see more of the guts of the macroexpanded source,
+@c      _   which is useful when debugging macros.
+@c      _ \end{defvar}
+@c      _ 
+@c      _ \begin{defmac}{extensions:}{define-source-context}{%
+@c      _     \args{\var{name} \var{lambda-list} \mstar{form}}}
+@c      _ 
+@c      _   This macro defines how to extract an abbreviated source context from
+@c      _   the \var{name}d form when it appears in the compiler input.
+@c      _   \var{lambda-list} is a \code{defmacro} style lambda-list used to
+@c      _   parse the arguments.  The \var{body} should return a list of
+@c      _   subforms that can be printed on about one line.  There are
+@c      _   predefined methods for \code{defstruct}, \code{defmethod}, etc.  If
+@c      _   no method is defined, then the first two subforms are returned.
+@c      _   Note that this facility implicitly determines the string name
+@c      _   associated with anonymous functions.
+@c      _ \end{defmac}
+@c      _ 
+@c      _ -->
+
+@node  Diagnostic Severity
+@comment  node-name,  next,  previous,  up
+@subsection Diagnostic Severity
+@cindex Severity of compiler messages
+@cindex Compiler Diagnostic Severity
+@tindex @cl{error}
+@tindex @cl{warning}
+@tindex @cl{style-warning}
+@tindex @sbext{compiler-note}
+@tindex @sbext{code-deletion-note}
+
+There are four levels of compiler diagnostic severity: 
+
+@enumerate 1
+@item error
+@item warning
+@item style warning
+@item note
+@end enumerate
+
+The first three levels correspond to condition classes which are
+defined in the ANSI standard for Common Lisp and which have special
+significance to the @code{compile} and @code{compile-file} functions.
+These levels of compiler error severity occur when the compiler
+handles conditions of these classes. 
+
+The fourth level of compiler error severity, @emph{note}, corresponds
+to the @code{sb-ext:compiler-note}, and is used for problems which are
+too mild for the standard condition classes, typically hints about how
+efficiency might be improved. The @code{sb-ext:code-deletion-note}, a
+subtype of @code{compiler-note}, is signalled when the compiler
+deletes user-supplied code after proving that the code in question is
+unreachable.
+
+Future work for SBCL includes expanding this hierarchy of types to
+allow more fine-grained control over emission of diagnostic messages.
+
+@include condition-sb-ext-compiler-note.texinfo
+@include condition-sb-ext-code-deletion-note.texinfo
+
+
+@node Understanding Compiler Diagnostics
+@comment  node-name,  next,  previous,  up
+@subsection Understanding Compile Diagnostics
+
+The messages emitted by the compiler contain a lot of detail in a
+terse format, so they may be confusing at first. The messages will be
 illustrated using this example program:
 
 @lisp
@@ -41,40 +187,38 @@ The main problem with this program is that it is trying to add
 @code{3} to a symbol. Note also that the functions @code{roq} and
 @code{ploq} aren't defined anywhere.
 
-
 @menu
-* The Parts of the Error Message::  
+* The Parts of a Compiler Diagnostic::  
 * The Original and Actual Source::  
-* Error Severity::              
-* Errors During Macroexpansion::  
-* Read Errors::                 
+* The Processing Path::         
 @end menu
 
-@node  The Parts of the Error Message, The Original and Actual Source, Error Messages, Error Messages
+@node  The Parts of a Compiler Diagnostic
 @comment  node-name,  next,  previous,  up
-@subsection The Parts of the Error Message
+@subsubsection The Parts of a Compiler Diagnostic
 
 When processing this program, the compiler will produce this warning:
 
 @example
-file: /tmp/foo.lisp
-
-in: DEFUN FOO
-(ZOQ Y)
---> ROQ PLOQ + 
-==>
-Y
-caught WARNING:
-Result is a SYMBOL, not a NUMBER.
+; file: /tmp/foo.lisp
+; in: DEFUN FOO
+;     (ZOQ Y)
+; --> ROQ PLOQ
+; ==>
+;   (+ Y 3)
+;
+; caught WARNING:
+;   Asserted type NUMBER conflicts with derived type (VALUES SYMBOL &OPTIONAL).
 @end example
 
 In this example we see each of the six possible parts of a compiler
-error message:
+diagnostic:
 
 @enumerate
 
 @item
-@samp{File: /tmp/foo.lisp} This is the name of the file that the
+@findex @cl{with-compilation-unit}
+@samp{file: /tmp/foo.lisp} 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
@@ -82,51 +226,57 @@ during compilation of a large system, especially when
 
 @item
 @samp{in: DEFUN FOO} 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
-``@samp{def}''.  If there is no such enclosing ``@samp{def}'' form,
-then the outermost form is used.  If there are multiple @samp{def}
+for the diagnostic. It is obtained by taking the first two elements of
+the enclosing form whose first element is a symbol beginning with
+``@samp{def}''. If there is no such enclosing ``@samp{def}'' form,
+then the outermost form is used. If there are multiple @samp{def}
 forms, then they are all printed from the outside in, separated by
-@samp{=>}'s.  In this example, the problem was in the @code{defun} for
+@samp{=>}'s. In this example, the problem was in the @code{defun} for
 @code{foo}.
 
 @item
+@cindex Original Source
 @samp{(ZOQ Y)} This is the @dfn{original source} 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
+the diagnostic. Original source means that the form directly appeared
+in the original input to the compiler, i.e. in the lambda passed to
 @code{compile} or in the top level form read from the source file. In
 this example, the expansion of the @code{zoq} macro was responsible
-for the error.
+for the message.
 
 @item
-@samp{--> ROQ PLOQ +} This is the @dfn{processing path} 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 @code{roq},
-@code{ploq} and @code{+}.  These calls resulted from the expansion of
-the @code{zoq} macro.
+@cindex Processing Path
+@samp{--> ROQ PLOQ} This is the @dfn{processing path} that the
+compiler used to produce the code that caused the message to be
+emitted. 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 @code{roq} and @code{ploq}. These calls resulted from the
+expansion of the @code{zoq} macro.
 
 @item
-@samp{==> Y} This is the @dfn{actual source} 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
+@cindex Actual Source
+@samp{==> (+ Y 3)} This is the @dfn{actual source} responsible for the
+diagnostic. 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 @code{y}.
 
 @item
-@samp{caught WARNING: Result is a SYMBOL, not a NUMBER.}  This is the
-@dfn{explanation} of the problem. In this example, the problem is that
-@code{y} evaluates to a symbol, but is in a context where a number is
-required (the argument to @code{+}).
+@samp{caught WARNING: Asserted type NUMBER conflicts with derived type
+(VALUES SYMBOL &OPTIONAL).}  This is the @dfn{explanation} of the
+problem. In this example, the problem is that, while the call to
+@code{+} requires that its arguments are all of type @code{number},
+the compiler has derived that @code{y} will evaluate to a
+@code{symbol}.  Note that @samp{(VALUES SYMBOL &OPTIONAL)} expresses
+that @code{y} evaluates to precisely one value.
 
 @end enumerate
 
-Note that each part of the error message is distinctively marked:
+Note that each part of the message is distinctively marked:
 
 @itemize
 
@@ -143,72 +293,75 @@ Each line of the processing path is prefixed with @samp{-->}
 @item
 The actual source form is indented like the original source, but is
 marked by a preceding @samp{==>} line.
-  
+@comment no it isn't.
 
 @item
-The explanation is prefixed with the error severity, which can be
+The explanation is prefixed with the diagnostic severity, which can be
 @samp{caught ERROR:}, @samp{caught WARNING:}, @samp{caught
 STYLE-WARNING:}, or @samp{note:}.
 
 @end itemize
 
-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:
+Each part of the message is more specific than the preceding one. If
+consecutive messages are for nearby locations, then the front part of
+the 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:
 
 @example
-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
+; 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
 @end example
+@comment fixing that weird blank line might be good
 
 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
+second message. If consecutive messages are entirely identical, then
 the compiler prints only the first message, followed by: @samp{[Last
 message occurs @var{repeats} times]} where @var{repeats} is the number
 of times the message was given.
 
-If the source was not from a file, then no file line is printed.  If
+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.
 
 
-@node  The Original and Actual Source, Error Severity, The Parts of the Error Message, Error Messages
+@node  The Original and Actual Source
 @comment  node-name,  next,  previous,  up
-@subsection The Original and Actual Source
+@subsubsection The Original and Actual Source
+@cindex Original Source
+@cindex Actual Source
 
 The @emph{original source} 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.)
+the actual source for an 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.)
 
 When the @emph{actual source} 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
+source-to-source compiler optimization. This is code that did not
 appear in the original source program; it was introduced by the
 compiler.
 
-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
+Keep in mind that when the compiler displays a source form in an
+diagnostic message, it always displays the most specific (innermost)
+responsible form. For example, compiling this function
 
 @lisp
 (defun bar (x)
@@ -221,20 +374,26 @@ form.  For example, compiling this function
 gives this error message
 
 @example
-in: DEFUN BAR
-(LET (A) (DECLARE (FIXNUM A)) (SETQ A (FOO X)) A)
-caught WARNING: The binding of A is not a FIXNUM:
-NIL
+; file: /tmp/foo.lisp
+; in: DEFUN BAR
+;     (LET (A)
+;     (DECLARE (FIXNUM A))
+;     (SETQ A (FOO X))
+;     A)
+;
+; caught WARNING:
+;   Asserted type FIXNUM conflicts with derived type (VALUES NULL &OPTIONAL).
 @end example
 
-This error message is not saying ``there is a problem somewhere in
-this @code{let}'' -- it is saying that there is a problem with the
+This message is not saying ``there is a problem somewhere in this
+@code{let}'' -- it is saying that there is a problem with the
 @code{let} itself. In this example, the problem is that @code{a}'s
 @code{nil} initial value is not a @code{fixnum}.
 
-
-@subsection The Processing Path
-@cindex Processing path
+@node The Processing Path
+@comment  node-name,  next,  previous,  up
+@subsubsection The Processing Path
+@cindex Processing Path
 @cindex Macroexpansion
 @cindex Source-to-source transformation
 
@@ -249,13 +408,14 @@ don't write macros, you can probably ignore it. Consider this example:
 Compiling results in this error message:
 
 @example
-in: DEFUN FOO
-(DOTIMES (I N *UNDEFINED*))
---> DO BLOCK LET TAGBODY RETURN-FROM
-==>
-(PROGN *UNDEFINED*)
-caught STYLE-WARNING:
-undefined variable: *UNDEFINED*
+; in: DEFUN FOO
+;     (DOTIMES (I N *UNDEFINED*))
+; --> DO BLOCK LET TAGBODY RETURN-FROM
+; ==>
+;   (PROGN *UNDEFINED*)
+;
+; caught WARNING:
+;   undefined variable: *UNDEFINED*
 @end example
 
 Note that @code{do} appears in the processing path. This is because
@@ -281,265 +441,122 @@ The rest of the processing path results from the expansion of
 @end lisp
 
 In this example, the compiler descended into the @code{block},
-@code{let}, @code{tagbody} and @code{return-from} to
-reach the @code{progn} printed as the actual source. This is a
-place where the ``actual source appears in explanation'' rule
-was applied. The innermost actual source form was the symbol
-@code{*undefined*} itself, but that also appeared in the
-explanation, so the compiler backed out one level.
+@code{let}, @code{tagbody} and @code{return-from} to reach the
+@code{progn} printed as the actual source. This is a place where the
+``actual source appears in explanation'' rule was applied. The
+innermost actual source form was the symbol @code{*undefined*} itself,
+but that also appeared in the explanation, so the compiler backed out
+one level.
 
 
-@node  Error Severity, Errors During Macroexpansion, The Original and Actual Source, Error Messages
-@comment  node-name,  next,  previous,  up
-@subsection Error Severity
-@cindex Severity of compiler errors
-@cindex compiler error severity
-
-There are four levels of compiler error severity: @emph{error},
-@emph{warning}, @emph{style warning}, and @emph{note}. The first three
-levels correspond to condition classes which are defined in the ANSI
-standard for Common Lisp and which have special significance to the
-@code{compile} and @code{compile-file} functions. These levels of
-compiler error severity occur when the compiler handles conditions of
-these classes. The fourth level of compiler error severity,
-@emph{note}, is used for problems which are too mild for the standard
-condition classes, typically hints about how efficiency might be
-improved.
-
-
-@node  Errors During Macroexpansion, Read Errors, Error Severity, Error Messages
-@comment  node-name,  next,  previous,  up
-@subsection Errors During Macroexpansion
-@cindex Macroexpansion, errors during
 
-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 @code{*break-on-signals*} to @code{error}. For
-example, this definition:
 
-@lisp
-(defun foo (e l)
-  (do ((current l (cdr current))
-       ((atom current) nil))
-      (when (eq (car current) e) (return current))))
-@end lisp
-
-gives this error:
 
-@example
-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)
-@end example
-
-
-@node  Read Errors,  , Errors During Macroexpansion, Error Messages
+@node  Handling of Types
 @comment  node-name,  next,  previous,  up
-@subsection Read Errors
-@cindex Read errors, compiler
+@section Handling of Types
 
-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.
-
-
-@c <!-- FIXME: How much control over error messages is in SBCL?
-@c      _     How much should be? How much of this documentation should
-@c      _     we save or adapt? 
-@c      _ 
-@c      _ %%\node Error Message Parameterization,  , Read Errors, Interpreting Error Messages
-@c      _ \subsection{Error Message Parameterization}
-@c      _ \cpsubindex{error messages}{verbosity}
-@c      _ \cpsubindex{verbosity}{of error messages}
-@c      _ 
-@c      _ There is some control over the verbosity of error messages.  See also
-@c      _ \varref{undefined-warning-limit}, \code{*efficiency-note-limit*} and
-@c      _ \varref{efficiency-note-cost-threshold}.
-@c      _ 
-@c      _ \begin{defvar}{}{enclosing-source-cutoff}
-@c      _ 
-@c      _   This variable specifies the number of enclosing actual source forms
-@c      _   that are printed in full, rather than in the abbreviated processing
-@c      _   path format.  Increasing the value from its default of \code{1}
-@c      _   allows you to see more of the guts of the macroexpanded source,
-@c      _   which is useful when debugging macros.
-@c      _ \end{defvar}
-@c      _ 
-@c      _ \begin{defvar}{}{error-print-length}
-@c      _   \defvarx{error-print-level}
-@c      _ 
-@c      _   These variables are the print level and print length used in
-@c      _   printing error messages.  The default values are \code{5} and
-@c      _   \code{3}.  If null, the global values of \code{*print-level*} and
-@c      _   \code{*print-length*} are used.
-@c      _ \end{defvar}
-@c      _ 
-@c      _ \begin{defmac}{extensions:}{define-source-context}{%
-@c      _     \args{\var{name} \var{lambda-list} \mstar{form}}}
-@c      _ 
-@c      _   This macro defines how to extract an abbreviated source context from
-@c      _   the \var{name}d form when it appears in the compiler input.
-@c      _   \var{lambda-list} is a \code{defmacro} style lambda-list used to
-@c      _   parse the arguments.  The \var{body} should return a list of
-@c      _   subforms that can be printed on about one line.  There are
-@c      _   predefined methods for \code{defstruct}, \code{defmethod}, etc.  If
-@c      _   no method is defined, then the first two subforms are returned.
-@c      _   Note that this facility implicitly determines the string name
-@c      _   associated with anonymous functions.
-@c      _ \end{defmac}
-@c      _ 
-@c      _ -->
+One of the most important features of the SBCL compiler (similar to
+the original CMUCL compiler, also known as @dfn{Python}) is its fairly
+sophisticated understanding of the Common Lisp type system and its
+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 in the chapter on performance (@pxref{Efficiency}), the use
+of appropriate type declarations can be very important for performance
+as well.
 
-@node  Handling of Types, Compiler Policy, Error Messages, The Compiler
-@comment  node-name,  next,  previous,  up
-@section The Compiler's Handling of Types
-
-The most unusual features of the SBCL compiler (which is very similar
-to the original CMUCL compiler, also known as @dfn{Python}) is its
-unusually sophisticated understanding of the Common Lisp 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 in the chapter on performance
-(@pxref{Efficiency}), the use of appropriate type declarations can be
-very important for performance as well.
-
-The SBCL compiler, like the related compiler in CMUCL, treats type
-declarations much differently than other Lisp compilers.  By default
-(@emph{i.e.}, at ordinary levels of the @code{safety} compiler
-optimization parameter), the compiler doesn't blindly believe most
-type declarations; it considers them assertions about the program that
-should be checked.
-
-The SBCL compiler also has a greater knowledge of the
-Common Lisp type system than other compilers.  Support is incomplete
-only for the @code{not}, @code{and} and @code{satisfies}
-types.
+@findex @cl{satisfies}
+The SBCL compiler also has a greater knowledge of the Common Lisp
+type system than other compilers. Support is incomplete only for types
+involving the @code{satisfies} type specifier.
 
 @c <!-- FIXME: See also sections \ref{advanced-type-stuff}
 @c      and \ref{type-inference}, once we snarf them from the
 @c      CMU CL manual. -->
-
+@c
+@c Also see my paper on improving Baker, when I get round to it.
+@c
+@c Whose paper?
 
 @menu
-* Implementation Limitations::  
-* Type Errors at Compile Time::  
+* Declarations as Assertions::  
 * Precise Type Checking::       
-* Weakened Type Checking::      
 * Getting Existing Programs to Run::  
+* Implementation Limitations::  
 @end menu
 
-@node  Implementation Limitations, Type Errors at Compile Time, Handling of Types, Handling of Types
+@node Declarations as Assertions
 @comment  node-name,  next,  previous,  up
-@subsection Implementation Limitations
+@subsection Declarations as Assertions
+@cindex Safety optimization quality
 
+The SBCL compiler treats type declarations differently from most other
+Lisp compilers. Under default compilation policy the compiler doesn't
+blindly believe type declarations, but considers them assertions about
+the program that should be checked: all type declarations that have
+not been proven to always hold are asserted at runtime.
 
-Ideally, the compiler would consider @emph{all} type declarations to
-be assertions, so that adding type declarations to a program, no
-matter how incorrect they might be, would @emph{never} cause undefined
-behavior. As of SBCL version 0.8.1, the compiler is known to fall
-short of this goal in two areas:
-
-  @itemize
-
-@item
-@code{Proclaim}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.
-
-@item
-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.
-
-@item
-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.
-
-@end itemize
+@quotation
+@emph{Remaining bugs in the compiler's handling of types unfortunately
+provide some exceptions to this rule, see @ref{Implementation
+Limitations}.}
+@end quotation
 
-These are important bugs, but are not necessarily easy to fix, so they
-may, alas, remain in the system for a while.
+CLOS slot types form a notable exception. Types declared using the
+@code{:type} slot option in @code{defclass} are asserted if and only
+if the class was defined in @emph{safe code} and the slot access
+location is in @emph{safe code} as well. This laxness does not pose
+any internal consistency issues, as the CLOS slot types are not
+available for the type inferencer, nor do CLOS slot types provide any
+efficiency benefits.
 
+There are three type checking policies available in SBCL, selectable
+via @code{optimize} declarations.
 
-@node  Type Errors at Compile Time, Precise Type Checking, Implementation Limitations, Handling of Types
-@comment  node-name,  next,  previous,  up
-@subsection Type Errors at Compile Time
-@cindex Compile time type errors
-@cindex Type checking, at compile time
+@table @strong
 
-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:
+@c FIXME: This should be properly integrated with general policy
+@c stuff, once that gets cleaned up.
 
+@item Full Type Checks
+All declarations are considered assertions to be checked at runtime,
+and all type checks are precise. The default compilation policy
+provides full type checks.
 
-@lisp
-(defun raz (foo)
-  (let ((x (case foo
-              (:this 13)
-              (:that 9)
-              (:the-other 42))))
-    (declare (fixnum x))
-    (foo x)))
-@end lisp
+Used when @code{(or (>= safety 2) (>= safety speed 1))}.
 
-Compilation produces this warning:
+@item Weak Type Checks
+Declared types may be simplified into faster to check supertypes: for
+example, @code{(or (integer -17 -7) (integer 7 17))} is simplified
+into @code{(integer -17 17)}.
 
-@example
-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
-@end example
+@strong{Note}: it is relatively easy to corrupt the heap when weak
+type checks are used if the program contains type-errors.
 
-In this case, the warning means that if @code{foo} isn't any of
-@code{:this}, @code{:that} or @code{:the-other}, then @code{x} will be
-initialized to @code{nil}, which the @code{fixnum} declaration makes
-illegal. The warning will go away if @code{ecase} is used instead of
-@code{case}, or if @code{:the-other} is changed to @code{t}.
+Used when @code{(and (< safety 2) (< safety speed))}
 
-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.
+@item No Type Checks
+All declarations are believed without assertions. Also disables
+argument count and array bounds checking.
 
+@strong{Note}: any type errors in code where type checks are not
+performed are liable to corrupt the heap.
 
-Type warnings are inhibited when the @code{sb-ext:inhibit-warnings}
-optimization quality is @code{3}. @xref{Compiler Policy}.  This
-can be used in a local declaration to inhibit type warnings in a code
-fragment that has spurious warnings.
+Used when @code{(= safety 0)}.
 
+@end table
 
-@node  Precise Type Checking, Weakened Type Checking, Type Errors at Compile Time, Handling of Types
+@node  Precise Type Checking
 @comment  node-name,  next,  previous,  up
 @subsection Precise Type Checking
 @cindex Precise type checking
 @cindex Type checking, precise
 
-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 @code{typep} had been called with the exact type specifier that
-appeared in the declaration. In SBCL, adding type declarations makes
-code safer.  (Except that remaining bugs in the compiler's handling of
-types unfortunately provide some exceptions to this rule, see
-@ref{Implementation Limitations}).
+Precise checking means that the check is done as though @code{typep}
+had been called with the exact type specifier that appeared in the
+declaration.
 
 If a variable is declared to be @code{(integer 3 17)} then its value
 must always be an integer between @code{3} and @code{17}. If multiple
@@ -547,53 +564,13 @@ 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 @code{and} type specifier.
 
-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.
-
-The types of structure slots are also checked. The value of a
-structure slot must always be of the type indicated in any
-@code{:type} slot option.
-
-In traditional Common Lisp 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.
-
 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 @code{or},
-@code{member}, and other list-style type specifiers.
+@code{member}, and other list-style type specifiers. 
 
 
-@node Weakened Type Checking, Getting Existing Programs to Run, Precise Type Checking, Handling of Types
-@comment  node-name,  next,  previous,  up
-@subsection Weakened Type Checking
-@cindex Weakened type checking
-@cindex Type checking, weakened
-
-At one time, CMUCL supported another level of type checking,
-``weakened type checking'', when the value for the @code{speed}
-optimization quality is greater than @code{safety}, and @code{safety}
-is not @code{0}.  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 @code{speed} to a higher level than @code{safety}, 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.
-
-
-@node  Getting Existing Programs to Run,  , Weakened Type Checking, Handling of Types
+@node  Getting Existing Programs to Run
 @comment  node-name,  next,  previous,  up
 @subsection Getting Existing Programs to Run
 @cindex Existing programs, to run
@@ -601,12 +578,11 @@ nonexistent runtime checking.
 @cindex Compatibility with other Lisps
 @c     (should also have an entry in the non-ANSI-isms section)-->
 
-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.
+Since SBCL'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.
 
 Some incorrect declarations can only be detected by run-time type
 checking. It is very important to initially compile a program with
@@ -739,74 +715,80 @@ variable in the loop body.
 @c <!-- FIXME: <xref>ND-variables, once we crib the text from the 
 @c      CMU CL manual. -->
 
-
-@node Compiler Policy, Open Coding and Inline Expansion, Handling of Types, The Compiler
+@node  Implementation Limitations
 @comment  node-name,  next,  previous,  up
-@section Compiler Policy
+@subsection Implementation Limitations
 
-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.
+Ideally, the compiler would consider @emph{all} type declarations to
+be assertions, so that adding type declarations to a program, no
+matter how incorrect they might be, would @emph{never} cause undefined
+behavior. However, the compiler is known to fall short of this goal in
+two areas:
 
-Compiler policy is controlled by the @code{optimize} declaration. The
-compiler supports the ANSI optimization qualities, and also an
-extension @code{sb-ext:inhibit-warnings}.
+@itemize
 
-Ordinarily, when the @code{speed} quality is high, the compiler emits
-notes to notify the programmer about its inability to apply various
-optimizations. Setting @code{sb-ext:inhibit-warnings} to a value at
-least as large as the @code{speed} 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.)
+@item
+@emph{Proclaimed} 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.
 
-@quotation
-Note: The basic functionality of the @code{optimize
-inhibit-warnings} 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
-@code{sb-ext:inhibit-notes}, so that what's currently written.
+@item
+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.
+
+For example,
 
 @lisp
-(declaim (optimize (sb-ext:inhibit-warnings 2)))
+(defun foo (x) 
+  (the integer (bar x)))
 @end lisp
 
-would become something like
+causes the following compiler diagnostic to be emitted:
+
+@example
+; note: type assertion too complex to check:
+;  (VALUES INTEGER &REST T).
+@end example
+
+A partial workaround is instead write:
 
 @lisp
-(declaim (sb-ext:inhibit-notes 2))
+(defun foo (x)
+  (the (values integer &optional) (bar x)))
 @end lisp
 
-@end quotation
+@end itemize
 
-In early versions of SBCL, a @code{speed} value of zero was used to
-enable byte compilation, but since version 0.7.0, SBCL only supports
-native compilation.
+These are important issues, but are not necessarily easy to fix, so
+they may, alas, remain in the system for a while.
 
-When @code{safety} is zero, almost all runtime checking of types,
-array bounds, and so forth is suppressed.
+@node Compiler Policy
+@comment  node-name,  next,  previous,  up
+@section Compiler Policy
 
-When @code{safety} is less than @code{speed}, any and all type checks
-may be suppressed. At some point in the past, CMUCL had a more nuanced
-interpretation of this (@pxref{Weakened Type Checking}). However, SBCL
-doesn't support that interpretation, and setting @code{safety} less
-than @code{speed} may have roughly the same effect as setting
-@code{safety} to zero.
+Compiler policy is controlled by the @code{optimize} declaration,
+supporting all ANSI optimization qualities (@code{debug},
+@code{safety}, @code{space}, and @code{speed}).@footnote{A deprecated
+extension @code{sb-ext:inhibit-warnings} is still supported, but
+liable to go away at any time.}
+
+For effects of various optimization qualities on type-safety and
+debuggability see @ref{Declarations as Assertions} and @ref{Debugger
+Policy Control}.
+
+Ordinarily, when the @code{speed} quality is high, the compiler emits
+notes to notify the programmer about its inability to apply various
+optimizations. For selective muffling of these notes @xref{Controlling
+Verbosity}.
 
 The value of @code{space} mostly influences the compiler's decision
 whether to inline operations, which tend to increase the size of
 programs. Use the value @code{0} 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.
+is to slow the program by causing cache misses or even swapping.
 
 @c <!-- FIXME: old CMU CL compiler policy, should perhaps be adapted
 @c      _    for SBCL. (Unfortunately, the CMU CL docs are out of sync with the
@@ -893,6 +875,7 @@ is to slow the program by causing cache misses or swapping.
 @c      _  In addition to suppressing type checks, \code{0} also suppresses
 @c      _  argument count checking, unbound-symbol checking and array bounds
 @c      _  checks.
+@c      _  ... and checking of tag existence in RETURN-FROM and GO.
 @c      _
 @c      _\item[\code{extensions:inhibit-warnings}] \cindex{inhibit-warnings
 @c      _    optimization quality}This is a CMU extension that determines how
@@ -941,13 +924,121 @@ is to slow the program by causing cache misses or swapping.
 @c      _(end of section on compiler policy)
 @c      _-->
 
+@include fun-sb-ext-describe-compiler-policy.texinfo
+@include fun-sb-ext-restrict-compiler-policy.texinfo
+@include macro-common-lisp-with-compilation-unit.texinfo
+
+@node Compiler Errors
+@comment  node-name,  next,  previous,  up
+@section Compiler Errors
+
+@menu
+* Type Errors at Compile Time::  
+* Errors During Macroexpansion::  
+* Read Errors::                 
+@end menu
+
+@node  Type Errors at Compile Time
+@comment  node-name,  next,  previous,  up
+@subsection Type Errors at Compile Time
+@cindex Compile time type errors
+@cindex Type checking, at compile time
+
+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:
+
+@lisp
+(defun raz (foo)
+  (let ((x (case foo
+              (:this 13)
+              (:that 9)
+              (:the-other 42))))
+    (declare (fixnum x))
+    (foo x)))
+@end lisp
+
+Compilation produces this warning:
+
+@example
+; 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
+@end example
+
+In this case, the warning means that if @code{foo} isn't any of
+@code{:this}, @code{:that} or @code{:the-other}, then @code{x} will be
+initialized to @code{nil}, which the @code{fixnum} declaration makes
+illegal. The warning will go away if @code{ecase} is used instead of
+@code{case}, or if @code{:the-other} is changed to @code{t}.
+
+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.
+
+@node  Errors During Macroexpansion
+@comment  node-name,  next,  previous,  up
+@subsection Errors During Macroexpansion
+@cindex Macroexpansion, errors during
+
+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 @code{*break-on-signals*} to @code{error}. For
+example, this definition:
+
+@lisp
+(defun foo (e l)
+  (do ((current l (cdr current))
+       ((atom current) nil))
+      (when (eq (car current) e) (return current))))
+@end lisp
+
+gives this error:
+
+@example
+; in: DEFUN FOO
+;     (DO ((CURRENT L (CDR CURRENT))
+;        ((ATOM CURRENT) NIL))
+;       (WHEN (EQ (CAR CURRENT) 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)
+@end example
+
 
-@node  Open Coding and Inline Expansion,  , Compiler Policy, The Compiler
+@node  Read Errors
+@comment  node-name,  next,  previous,  up
+@subsection Read Errors
+@cindex Read errors, compiler
+
+SBCL's compiler 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.
+
+@node  Open Coding and Inline Expansion
 @comment  node-name,  next,  previous,  up
 @section Open Coding and Inline Expansion
 @cindex Open-coding
-@cindex inline expansion
-@cindex static functions
+@cindex Inline expansion
+@cindex Static functions
 
 Since Common Lisp forbids the redefinition of standard functions, the
 compiler can have special knowledge of these standard functions
@@ -963,7 +1054,9 @@ 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
 @code{trace} macro.  Special-casing of standard functions can be
-inhibited using the @code{notinline} declaration.
+inhibited using the @code{notinline} declaration, but even then some
+phases of analysis such as type inferencing are applied by the
+compiler.
 
 @item
 The compiler can have multiple alternate implementations of standard
@@ -1017,3 +1110,19 @@ may be transformed into a different function call (as in the last
 example) or compiled as @emph{static call}. Static function call uses
 a more efficient calling convention that forbids redefinition.
 
+@node  Interpreter
+@comment  node-name,  next,  previous,  up
+@section Interpreter
+@cindex Interpreter
+@findex @cl{eval}
+@vindex @sbext{@earmuffs{evaluator-mode}}
+
+By default SBCL implements @code{eval} by calling the native code
+compiler.
+
+SBCL also includes an interpreter for use in special cases where using
+the compiler is undesirable, for example due to compilation overhead.
+Unlike in some other Lisp implementations, in SBCL interpreted code is
+not safer or more debuggable than compiled code.
+
+@include var-sb-ext-star-evaluator-mode-star.texinfo