0.8.3.62:
[sbcl.git] / doc / compiler.sgml
index a72bc1a..131508b 100644 (file)
@@ -274,10 +274,10 @@ gives this error:
 
 <screen>in: DEFUN FOO
   (DO ((CURRENT L #) (# NIL)) (WHEN (EQ # E) (RETURN CURRENT)) )
-caught ERROR: (during macroexpansion)
-
-error in function LISP::DO-DO-BODY:
-   DO step variable is not a symbol: (ATOM CURRENT)</screen>
+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>
@@ -376,11 +376,19 @@ types.
 Ideally, the compiler would consider <emphasis>all</> type declarations to
 be assertions, so that adding type declarations to a program, no
 matter how incorrect they might be, would <emphasis>never</> cause
-undefined behavior. As of &SBCL; version 0.6.4, the compiler is known to
+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>The compiler trusts function return values which 
-    have been established with <function>proclaim</>.</para></listitem>
+  <listitem><para><function>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.</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
@@ -439,44 +447,39 @@ an error if it is executed) and gives a warning.</para>
 
 <para>
 Type warnings are inhibited when the
-<parameter>extensions:inhibit-warnings</> optimization quality is
-<literal>3</>. (See <link linkend="compiler-policy">the section 
+<parameter>sb-ext:inhibit-warnings</> optimization quality is
+<literal>3</>. (See <link linkend="compiler-policy">the section
 on compiler policy</>.) This can be used in a local declaration
 to inhibit type warnings in a code fragment that has spurious
 warnings.</para>
 
 </sect2>
 
-<sect2><title>Precise Type Checking</>
+<sect2 id="precisetypechecking"><title>Precise Type Checking</>
 <!--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 (such as using
-<function>the</> to constrain the argument type passed to a function)
-where they are simply ignored instead. Precise checking means that the
-check is done as though <function>typep</> 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>
+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</> 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)</>
-then its
-value must always always be an integer between <literal>3</>
-and <literal>17</>.
-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 specifier.</para>
-
-<para>Argument 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, which means that a more restrictive type
-assertion in the calling function (e.g., from <function>the</>) may be
-lost.</para>
+<type>(integer 3 17)</> then its value must always be an integer
+between <literal>3</> and <literal>17</>. 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 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
@@ -509,84 +512,14 @@ slots as precisely as possible. This often involves the use of
 <quote>weakened type checking</>, when the value for the
 <parameter>speed</> optimization quality is greater than
 <parameter>safety</>, and <parameter>safety</> is not <literal>0</>.
-The &CMUCL; manual still has a description of it, but the code no
-longer corresponds to the manual. It sounds like a good thing to have,
-and we might someday be able to restore it in &SBCL; but in the
-meantime, if you ask the compiler to optimize <parameter>speed</> to a
-higher level than <parameter>safety</>, your program is performing
-without a safety net, because &SBCL; may believe any or all type
-declarations without any runtime checking at all.</para>
-
-<!-- (beginning of text adapted from out-of-date CMUCL manual, describing
-_    features it would be nice for SBCL to restore someday)
-_ 
-_ <para>When the value for the <parameter>speed</> optimization quality
-_ is greater than <parameter>safety</>, and <parameter>safety</> is not
-_ <literal>0</>, then type checking is weakened to reduce the speed and
-_ space penalty. In structure-intensive code this can double the speed,
-_ yet still catch most type errors. Weakened type checks provide a level
-_ of safety similar to that of <quote>safe</> code in other &CommonLisp;
-_ compilers.</para>
-_ 
-_ <para>A type check is weakened by changing the check to be for some
-_ convenient supertype of the asserted type. For example, <type>(integer
-_ 3 17)</> is changed to <type>fixnum</>, <type>(simple-vector 17)</> to
-_ <type>simple-vector</>, and structure types are changed to
-_ <type>structure-object</>. A test for a complex type like <type>(or node hunk
-_ (member :foo :bar :baz))</> will be omitted entirely (i.e., the type
-_ is weakened to <type>*</>.) If a precise check can be done for no
-_ extra cost, then no weakening is done.</para>
-_ 
-_ <para>Although weakened type checking is similar to type checking done
-_ by other compilers, it is sometimes safer and sometimes less safe.
-_ Weakened checks are done in the same places is precise checks, so all
-_ the preceding discussion about where checking is done still applies.
-_ Weakened checking is sometimes somewhat unsafe because although the
-_ check is weakened, the precise type is still input into type
-_ inference. In some contexts this will result in type inferences not
-_ justified by the weakened check, and hence deletion of some type
-_ checks that would be done by conventional compilers.</para>
-_ 
-_ <para>For example, if this code was compiled with weakened checks
-_ 
-_ <programlisting>(defstruct foo
-_   (a nil :type simple-string))
-_ 
-_ (defstruct bar
-_   (a nil :type single-float))
-_ 
-_ (defun myfun (x)
-_   (declare (type bar x))
-_   (* (bar-a x) 3.0))</programlisting>
-_ 
-_ and <function>myfun</> was passed a value of
-_ type <type>foo</>, then no type error would be
-_ signaled, and we would try to multiply a <type>simple-vector</> as
-_ though it were a <type>single-float</> (with unpredictable results.)
-_ This is because the check for <type>bar</> was weakened to
-_ <type>structure-object</>, yet when compiling the call to <type>bar-a</>, the
-_ compiler thinks it knows it has a <type>bar</>.</para>
-_ 
-_ <para>Note that normally even weakened type checks report the precise
-_ type in error messages. For example, if <function>myfun</>'s
-_ <type>bar</> check is weakened to <type>structure-object</>, and the argument
-_ is <literal>nil</>, then the error will be:
-_ 
-_ <screen>Type-error in MYFUN:
-_   NIL is not of type BAR</screen>
-_ 
-_ However, there is some speed and space cost for signaling a precise
-_ error, so the weakened type is reported if the <parameter>speed</>
-_ optimization quality is <literal>3</> or <parameter>debug</>
-_ quality is less than <literal>1</>:
-_ 
-_ <screen>Type-error in MYFUN:
-_   NIL is not of type STRUCTURE-OBJECT</screen>
-_ 
-_ </para>
-_ 
-_ (end of text adapted from out-of-date CMUCL manual, describing
-_ features it would be nice for SBCL to restore someday) -->
+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</> to a higher level than <parameter>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.</para>
 
 </sect2>
 
@@ -596,20 +529,21 @@ _ features it would be nice for SBCL to restore someday) -->
 <!--INDEX {compatibility with other Lisps}
     (should also have an entry in the non-&ANSI;-isms section)-->
 
-<para>Since &SBCL;'s compiler does much more comprehensive type
-checking than other Lisp compilers, &SBCL; will detect type errors in
-many 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>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 programs with
-full type checks and then test this 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
+type checking. It is very important to initially compile a program
+with full type checks (high <parameter>safety</> 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
@@ -670,9 +604,7 @@ type of the result of evaluating a macro argument, then put a
   `(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. Macros have no
-efficiency advantage over inline functions when using the
-&SBCL; compiler.
+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>
@@ -704,15 +636,15 @@ compiled using other compilers.</para>
 
 <para>In this case, the fix is to weaken the type declaration to
 <type>(or fixnum null)</>.
-<footnote><para>Actually, this declaration is unnecessary
-  unnecessary in &SBCL;, since it already knows <function>position</>
+<footnote><para>Actually, this declaration is 
+  unnecessary in &SBCL;, since it already knows that <function>position</>
   returns a non-negative <type>fixnum</> or <literal>nil</>.
   </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 the variable is a <type>fixnum</>, since <literal>nil</> is not a legal
-numeric argument.  Another possible fix would be to say:
+declaration in this way. Any numeric operations in the body can still
+assume that the variable is a <type>fixnum</>, since <literal>nil</>
+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))
@@ -727,10 +659,6 @@ variable in the loop body.
      CMU CL manual. -->
 </para>
 
-<para>In summary, remember that <emphasis>all</> values that a variable
-<emphasis>ever</> has must be of the declared type, and that you
-should test using safe compilation options initially.</para>
-
 </sect2>
 
 </sect1>
@@ -738,7 +666,7 @@ should test using safe compilation options initially.</para>
 <sect1 id="compiler-policy"><title>Compiler Policy</>
 
 <para>As of version 0.6.4, &SBCL; still uses most of the &CMUCL; code
-for compiler policy. Thi &CMUCL; code has many features and high-quality
+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
@@ -756,8 +684,8 @@ the <parameter>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 useful for code which truly can't guarantee that its arguments
-will always be fixnums.)</para>
+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</> extension will probably be supported in all future
@@ -766,8 +694,8 @@ 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 SB-EXT:INHIBIT-NOTES, so that
-what's currently written
+declaration identifier with a name like
+<parameter>sb-ext:inhibit-notes</>, so that what's currently written
 
 <programlisting>(declaim (optimize (sb-ext:inhibit-warnings 2)))</>
 
@@ -787,16 +715,16 @@ of types, array bounds, and so forth is suppressed.</para>
 <para>When <parameter>safety</> is less than <parameter>speed</>, 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> At some point in the future, &SBCL; may
-restore that interpretation, or something like it. Until then, setting
-<parameter>safety</> less than <parameter>speed</> may have roughly
-the same effect as setting <parameter>safety</> to zero.</para>
+interpretation of this</link>. However, &SBCL; doesn't support that
+interpretation, and setting <parameter>safety</> less than
+<parameter>speed</> may have roughly the same effect as setting
+<parameter>safety</> to zero.</para>
 
 <para>The value of <parameter>space</> mostly influences the
 compiler's decision whether to inline operations, which tend to
 increase the size of programs. Use the value <literal>0</> with
 caution, since it can cause the compiler to inline operations so
-promiscuously that the net effect is to slow the program by causing
+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
@@ -865,7 +793,7 @@ _
 _\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 promiscuous inline expansion.  Wide use of a
+_  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.