0.7.9.36:
[sbcl.git] / doc / beyond-ansi.sgml
index 3c1a434..e175fa4 100644 (file)
-<chapter id="beyond-ansi"><title>Beyond the &ANSI; Standard</>
-
-<para>Besides &ANSI;, we have other stuff..</para>
-
-<sect1 id="non-conformance"><title>Non-Conformance with the &ANSI; Standard</>
-
-<para>&SBCL; is derived from code which was written before the &ANSI;
-standard, and some incompatibilities remain.</para>
-
-<para>The &ANSI; standard defines constructs like
-<function>defstruct</>, <function>defun</>, and <function>declaim</>
-so that they can be implemented as macros which expand into ordinary
-code wrapped in <function>eval-when</> forms. However, the pre-&ANSI;
-&CMUCL; implementation handled these (and some related functions like
-<function>proclaim</>) as special cases in the compiler, with subtly
-(or sometimes not-so-subtly) different semantics. Much of this
-weirdness has been removed in the years since the &ANSI; standard was
-released, but bits and pieces remain, so that e.g., as of &SBCL; 0.6.3
-compiling the function
-
-<programlisting>(defun foo () (defstruct bar))</>
-
-will cause the class <type>BAR</> to be defined, even when the
-function is not executed. These remaining nonconforming behaviors are
-considered bugs, and clean patches will be gratefully accepted, but as
-long as they don't cause as many problems in practice as other known
-issues, they tend not to be actively fixed.</para>
-
-<para>More than any other &Lisp; system I am aware of, &SBCL; (and its
-parent &CMUCL;) store and use a lot of compile-time static type
-information. By and large they conform to the standard in doing so,
-but in one regard they do not &mdash; they consider <function>defun</>s to,
-in effect, implicitly <function>proclaim</> type information about the
-signature of the function being defined. Thus, if you compile and load
-
-<programlisting>(defun foo-p (x)
-  (error "stub, foo-p ~s isn't implemented yet!" x))
-(defun foolike-p (x)
-  (or (foo-p x) (foo-p (car x))))</programlisting>
-
-everything will appear to work correctly, but if you subsequently
-redefine <function>foo-p</>
-
-<programlisting>(defun foo-p (x) (or (null x) (symbolp (car x))))</>
-
-and call
-
-<programlisting>(foolike-p nil)</>
-
-you will not get the correct result, but an error,
-
-<screen>debugger invoked on SB-DEBUG::*DEBUG-CONDITION* of type
-SB-KERNEL:SIMPLE-CONTROL-ERROR:
-  A function with declared result type NIL returned:
-  FOO-P</screen>
-
-because when &SBCL; compiled <function>foolike-p</>, &SBCL; thought it
-knew that <function>foo-p</> would never return. More insidious
-problems are quite possible when &SBCL; thinks it can optimize away e.g.
-particular branches of a <function>case</> because of what it's proved
-to itself about the function's return type. This will probably be
-fixed in the foreseeable future, either with a quick fix, or ideally
-in conjunction with some related fixes to generalize the principle
-that declarations are assertions (see below). But for now it remains a
-gross violation of the &ANSI; spec (and reasonable user
-expectations).</para>
-
-<para>The &CMUCL; <function>defstruct</> implementation treated
-structure accessors and other <function>defstruct</>-related functions
-(e.g. predicates) as having some special properties, not quite like
-ordinary functions. This specialness has been reduced in &SBCL;, but
-some still remains. In particular, redefining a structure accessor
-function may magically cause the entire structure class to be deleted.
-This, too, will probably be fixed in the foreseeable future.</para>
-
-<para>The CLOS implementation used in &SBCL; is based on the
-<application>Portable Common Loops</> (PCL) reference implementation
-from Xerox. Unfortunately, PCL seems never to have quite conformed to
-the final CLOS specification. Moreover, despite the "Portable" in its
-name, it wasn't quite portable. Various implementation-specific hacks
-were made to make it run on &CMUCL;, and then more hacks were added to
-make it less inefficient. The result is a system with mostly tolerable
-performance which mostly conforms to the standard, but which has a few
-remaining weirdnesses which seem to be hard to fix. The most important
-remaining weirdness is that the <type>CL:CLASS</> class is not the
-same as the <type>SB-PCL:CLASS</> type used internally in PCL; and
-there are several other symbols maintained in parallel (e.g.
-<type>SB-PCL:FIND-CLASS</> vs. <type>CL:FIND-CLASS</>). So far, any
-problems this has caused have had workarounds involving consistently
-using the SB-PCL versions or the CL versions of the class hierarchy.
-This is admittedly ugly, but it may not be fixed in the foreseeable
-future, since the required cleanup looks nontrivial, and we don't have
-anyone sufficiently motivated to do it.</para>
+<chapter id="beyond-ansi"><title>Beyond The &ANSI; Standard</>
+
+<para>&SBCL; is mostly an implementation of the &ANSI; standard for
+Common Lisp. However, there's some important behavior which extends
+or clarifies the standard, and various behavior which outright
+violates the standard.
+</para>
+
+<sect1 id="non-conformance"><title>Non-Conformance With The &ANSI; Standard</>
+
+<para>
+Essentially every type of non-conformance is considered a bug.
+(The exceptions involve internal inconsistencies in the standard.)
+In &SBCL; 0.7.6, the master record of known bugs is in
+the <filename>BUGS</> file in the distribution.
+Some highlight information about bugs may also be found in the
+manual page. The recommended way to report bugs is through the sbcl-help or
+sbcl-devel mailings lists.
+</para>
 
 </sect1>
 
 <sect1 id="idiosyncrasies"><title>Idiosyncrasies</>
 
+<para>The information in this section describes some of the ways
+that &SBCL; deals with choices that the &ANSI; standard 
+leaves to the implementation.</para>
+
 <para>Declarations are generally treated as assertions. This general
 principle, and its implications, and the bugs which still keep the
 compiler from quite satisfying this principle, are discussed in the
 <link linkend="compiler">chapter on the compiler</link>.</para>
 
-<note><para>It's not an idiosyncrasy yet, since we haven't done
-it, but someday soon &SBCL; may become a compiler-only implementation.
-That is, essentially, <function>eval</> will be defined to create
-a lambda expression, call <function>compile</> on the lambda
-expression to create a compiled function, and then
-<function>funcall</> the resulting function. This would allow
-a variety of simplifications in the implementation, while introducing
-some other complexities. It remains to be seen when it will be
-possible to try this, or whether it will work well when it's tried,
-but it looks appealing right now.</para></note>
+<para>&SBCL; is essentially a compiler-only implementation of
+&CommonLisp;. That is, for all but a few special cases,
+<function>eval</> creates a
+lambda expression, calls <function>compile</> on the lambda
+expression to create a compiled function, and then calls
+<function>funcall</> on the resulting function object. This 
+is explicitly allowed by the &ANSI; standard, but leads to some
+oddities, e.g. collapsing <function>functionp</> and 
+<function>compiled-function-p</> into the same predicate.</para>
+
+<para>&SBCL; is quite strict about ANSI's definition of
+<function>defconstant</>. ANSI says that doing <function>defconstant</>
+of the same symbol more than once is undefined unless the new value
+is <function>eql</> to the old value. Conforming to this specification
+is a nuisance when the "constant" value is only constant under some
+weaker test like <function>string=</> or <function>equal</>. It's
+especially annoying because <function>defconstant</> takes effect
+not only at load time but also at compile time, so that just 
+compiling and loading reasonable code like 
+<programlisting>(defconstant +foobyte+ '(1 4))</>
+runs into this undefined behavior. Many
+implementations of Common Lisp try to help the programmer around
+this annoyance by silently accepting the undefined code and 
+trying to do what the programmer probably meant. &SBCL; instead
+treats the undefined behavior as an error. Often
+such code can be rewritten
+in portable &ANSI; Common Lisp which has the desired behavior.
+E.g., the code above can be given an exactly defined meaning by replacing
+<function>defconstant</> either with <function>defparameter</> or 
+with a customized macro which does the right thing, possibly along the
+lines of the <function>defconstant-eqx</> macro used internally in the
+implementation of SBCL itself.</para>
+
+<para>&SBCL; gives style warnings about various kinds of perfectly
+legal code, e.g.
+<itemizedlist>
+  <listitem><para><function>defmethod</> without
+    <function>defgeneric</></para></listitem>
+  <listitem><para>multiple <function>defun</>s of the same
+    symbol</para></listitem>
+  <listitem><para>special variables not named in the conventional
+    <varname>*foo*</> style, and lexical variables unconventionally named
+    in the <varname>*foo*</> style</para></listitem>
+</itemizedlist>
+This causes friction with people
+who point out that other ways of organizing code (especially
+avoiding the use of <function>defgeneric</>)
+are just as aesthetically stylish.
+However, these warnings should be read not
+as "warning, bad aesthetics detected, you have no style" but
+"warning, this style keeps the compiler from understanding
+the code as well as you might like." That is, 
+unless the compiler warns about such conditions, there's no
+way for the compiler to warn 
+about some programming errors which would otherwise be
+easy to overlook. (related bug: The warning about
+multiple <function>defun</>s is pointlessly annoying when you compile
+and then load a function containing <function>defun</> wrapped
+in <function>eval-when</>, and ideally should be suppressed in 
+that case, but still isn't as of &SBCL; 0.7.6.)</para>
 
 </sect1>
 
 <sect1 id="extensions"><title>Extensions</>
 
-<para>&SBCL; is derived from &CMUCL;, which implements many extensions to the
-&ANSI; standard. &SBCL; doesn't support as many extensions as &CMUCL;, but
-it still has quite a few.</para>
+<para>&SBCL; is derived from &CMUCL;, which implements many extensions
+to the &ANSI; standard. &SBCL; doesn't support as many extensions as
+&CMUCL;, but it still has quite a few.</para>
 
-<sect2><title>Things Which Might Be in the Next &ANSI; Standard</>
+<sect2><title>Things Which Might Be In The Next &ANSI; Standard</>
 
 <para>&SBCL; provides extensive support for 
 calling external C code, described 
@@ -130,21 +110,23 @@ calling external C code, described
 specified by &ANSI;. Weak pointers allow references to objects to be
 maintained without keeping them from being GCed. And "finalization"
 hooks are available to cause code to be executed when an object is
-GCed.</para>
+GCed.</para> <!-- FIXME: Actually documenting these would be good.:-| -->
 
-<para>&SBCL; does not currently provide Gray streams, but may do so in
-the near future. (It has unmaintained code inherited from &CMUCL; to
-do so.) <!-- FIXME: Add citation to Gray streams.-->
-</para>
+<para>&SBCL; supports Gray streams, user-overloadable CLOS classes
+whose instances can be used as Lisp streams (e.g. passed as the
+first argument to <function>format</>).</para>
 
-<para>&SBCL; does not currently support multithreading (traditionally
-called <wordasword>multiprocessing</> in &Lisp;) but contains unmaintained
-code from &CMUCL; to do so. A sufficiently motivated maintainer
-could probably make it work.</para>
+<para>&SBCL; supports a MetaObject Protocol which is intended to be
+compatible with &AMOP;; exceptions to this (as distinct from current
+bugs<!-- Such as the distinction between CL:FIND-CLASS and
+SB-PCL::FIND-CLASS :-( -->) are that
+<function>compute-effective-method</> only returns one value, not
+two<!-- FIXME: anything else? What about extensions? (e.g. COMPUTE-SLOTS
+behaviour) -->.</para>
 
 </sect2>
 
-<sect2><title>Support for Unix</>
+<sect2><title>Support For Unix</>
 
 <para>The UNIX command line can be read from the variable
 <varname>sb-ext:*posix-argv*</>. The UNIX environment can be queried with the
@@ -157,7 +139,7 @@ is also supported.</para>
 
 </sect2>
 
-<sect2><title>Tools to Help Developers</title>
+<sect2><title>Tools To Help Developers</title>
 
 <para>&SBCL; provides a profiler and other extensions to the &ANSI;
 <function>trace</> facility. See the online function documentation for
@@ -165,13 +147,21 @@ is also supported.</para>
 
 <para>The debugger supports a number of options. Its documentation is
 accessed by typing <userinput>help</> at the debugger prompt.</para>
+<!-- FIXME:
+     A true debugger section in the manual would be good. Start
+     with CMU CL's debugger section, but remember:
+       * no QUIT command (TOPLEVEL restart instead)
+       * no GO command (CONTINUE restart instead)
+       * Limitations of the x86 port of the debugger should be 
+         documented or fixed where possible.
+       * Discuss TRACE and its unification with PROFILE. -->
 
 <para>Documentation for <function>inspect</> is accessed by typing
 <userinput>help</> at the <function>inspect</> prompt.</para>
 
 </sect2>
 
-<sect2><title>Interface to Low-Level &SBCL; Implementation</title>
+<sect2><title>Interface To Low-Level &SBCL; Implementation</title>
 
 <para>&SBCL; has the ability to save its state as a file for later
 execution. This functionality is important for its bootstrapping
@@ -194,7 +184,7 @@ look good, and their interface looks good, but &IEEE; support is
 slightly broken due to a stupid decision to remove some support for
 infinities (because it wasn't in the &ANSI; spec and it didn't occur to
 me that it was in the &IEEE; spec). If you need this stuff, take a look
-at the ecode and bring it up on the developers' mailing
+at the code and bring it up on the developers' mailing
 list.</para></note>
 
 </sect2>
@@ -203,16 +193,20 @@ list.</para></note>
 
 <para>The <function>sb-ext:purify</function> function causes &SBCL;
 first to collect all garbage, then to mark all uncollected objects as
-permanent, never again attempting to collect them as garbage. (This
-can cause a large increase in efficiency when using a primitive
-garbage collector, but is less important with modern generational
-garbage collectors.)</para>
+permanent, never again attempting to collect them as garbage. This can
+cause a large increase in efficiency when using a primitive garbage
+collector, or a more moderate increase in efficiency when using a more
+sophisticated garbage collector which is well suited to the program's
+memory usage pattern. It also allows permanent code to be frozen at
+fixed addresses, a precondition for using copy-on-write to share code
+between multiple Lisp processes. is less important with modern
+generational garbage collectors. </para>
 
 <para>The <function>sb-ext:truly-the</> operator does what the
 <function>cl:the</> operator does in a more conventional
 implementation of &CommonLisp;, declaring the type of its argument
-without any runtime checks. (Ordinarily in &SBCL;, any type declaration
-is treated as an assertion and checked at runtime.)</para>
+without any runtime checks. (Ordinarily in &SBCL;, any type
+declaration is treated as an assertion and checked at runtime.)</para>
 
 <para>The <function>sb-ext:freeze-type</> declaration declares that a
 type will never change, which can make type testing
@@ -220,9 +214,10 @@ type will never change, which can make type testing
 
 <para>The <function>sb-ext:constant-function</> declaration specifies
 that a function will always return the same value for the same
-arguments. This is appropriate for functions like <function>sqrt</>.
-It is not appropriate for functions like <function>aref</>, which can
-change their return values when the underlying data are
+arguments, which may allow the compiler to optimize calls
+to it. This is appropriate for functions like <function>sqrt</>, but
+is <emphasis>not</> appropriate for functions like <function>aref</>,
+which can change their return values when the underlying data are
 changed.</para>
 
 </sect2>