a3d7eea9c5ca60ec86cd36b4e84e6649f5e27488
[sbcl.git] / doc / beyond-ansi.sgml
1 <chapter id="beyond-ansi"><title>Beyond the &ANSI; Standard</>
2
3 <para>Besides &ANSI;, we have other stuff..</para>
4
5 <sect1 id="non-conformance"><title>Non-Conformance with the &ANSI; Standard</>
6
7 <para>&SBCL; is derived from code which was written before the &ANSI;
8 standard, and some incompatibilities remain.</para>
9
10 <para>The &ANSI; standard defines constructs like
11 <function>defstruct</>, <function>defun</>, and <function>declaim</>
12 so that they can be implemented as macros which expand into ordinary
13 code wrapped in <function>eval-when</> forms. However, the pre-&ANSI;
14 &CMUCL; implementation handled these (and some related functions like
15 <function>proclaim</>) as special cases in the compiler, with subtly
16 (or sometimes not-so-subtly) different semantics. Much of this
17 weirdness has been removed in the years since the &ANSI; standard was
18 released, but bits and pieces remain, so that e.g., as of &SBCL; 0.6.3
19 compiling the function
20
21 <programlisting>(defun foo () (defstruct bar))</>
22
23 will cause the class <type>BAR</> to be defined, even when the
24 function is not executed. These remaining nonconforming behaviors are
25 considered bugs, and clean patches will be gratefully accepted, but as
26 long as they don't cause as many problems in practice as other known
27 issues, they tend not to be actively fixed.</para>
28
29 <para>More than any other &Lisp; system I am aware of, &SBCL; (and its
30 parent &CMUCL;) store and use a lot of compile-time static type
31 information. By and large they conform to the standard in doing so,
32 but in one regard they do not &mdash; they consider <function>defun</>s to,
33 in effect, implicitly <function>proclaim</> type information about the
34 signature of the function being defined. Thus, if you compile and load
35
36 <programlisting>(defun foo-p (x)
37   (error "stub, foo-p ~s isn't implemented yet!" x))
38 (defun foolike-p (x)
39   (or (foo-p x) (foo-p (car x))))</programlisting>
40
41 everything will appear to work correctly, but if you subsequently
42 redefine <function>foo-p</>
43
44 <programlisting>(defun foo-p (x) (or (null x) (symbolp (car x))))</>
45
46 and call
47
48 <programlisting>(foolike-p nil)</>
49
50 you will not get the correct result, but an error,
51
52 <screen>debugger invoked on SB-DEBUG::*DEBUG-CONDITION* of type
53 SB-KERNEL:SIMPLE-CONTROL-ERROR:
54   A function with declared result type NIL returned:
55   FOO-P</screen>
56
57 because when &SBCL; compiled <function>foolike-p</>, &SBCL; thought it
58 knew that <function>foo-p</> would never return. More insidious
59 problems are quite possible when &SBCL; thinks it can optimize away e.g.
60 particular branches of a <function>case</> because of what it's proved
61 to itself about the function's return type. This will probably be
62 fixed in the foreseeable future, either with a quick fix, or ideally
63 in conjunction with some related fixes to generalize the principle
64 that declarations are assertions (see below). But for now it remains a
65 gross violation of the &ANSI; spec (and reasonable user
66 expectations).</para>
67
68 <para>The &CMUCL; <function>defstruct</> implementation treated
69 structure accessors and other <function>defstruct</>-related functions
70 (e.g. predicates) as having some special properties, not quite like
71 ordinary functions. This specialness has been reduced in &SBCL;, but
72 some still remains. In particular, redefining a structure accessor
73 function may magically cause the entire structure class to be deleted.
74 This, too, will probably be fixed in the foreseeable future.</para>
75
76 <para>The CLOS implementation used in &SBCL; is based on the
77 <application>Portable Common Loops</> (PCL) reference implementation
78 from Xerox. Unfortunately, PCL seems never to have quite conformed to
79 the final CLOS specification. Moreover, despite the "Portable" in its
80 name, it wasn't quite portable. Various implementation-specific hacks
81 were made to make it run on &CMUCL;, and then more hacks were added to
82 make it less inefficient. The result is a system with mostly tolerable
83 performance which mostly conforms to the standard, but which has a few
84 remaining weirdnesses which seem to be hard to fix. The most important
85 remaining weirdness is that the <type>CL:CLASS</> class is not the
86 same as the <type>SB-PCL:CLASS</> type used internally in PCL; and
87 there are several other symbols maintained in parallel (e.g.
88 <type>SB-PCL:FIND-CLASS</> vs. <type>CL:FIND-CLASS</>). So far, any
89 problems this has caused have had workarounds involving consistently
90 using the SB-PCL versions or the CL versions of the class hierarchy.
91 This is admittedly ugly, but it may not be fixed in the foreseeable
92 future, since the required cleanup looks nontrivial, and we don't have
93 anyone sufficiently motivated to do it.</para>
94
95 </sect1>
96
97 <sect1 id="idiosyncrasies"><title>Idiosyncrasies</>
98
99 <para>Declarations are generally treated as assertions. This general
100 principle, and its implications, and the bugs which still keep the
101 compiler from quite satisfying this principle, are discussed in the
102 <link linkend="compiler">chapter on the compiler</link>.</para>
103
104 <note><para>It's not an idiosyncrasy yet, since we haven't done
105 it, but someday soon &SBCL; may become a compiler-only implementation.
106 That is, essentially, <function>eval</> will be defined to create
107 a lambda expression, call <function>compile</> on the lambda
108 expression to create a compiled function, and then
109 <function>funcall</> the resulting function. This would allow
110 a variety of simplifications in the implementation, while introducing
111 some other complexities. It remains to be seen when it will be
112 possible to try this, or whether it will work well when it's tried,
113 but it looks appealing right now.</para></note>
114
115 </sect1>
116
117 <sect1 id="extensions"><title>Extensions</>
118
119 <para>&SBCL; is derived from &CMUCL;, which implements many extensions to the
120 &ANSI; standard. &SBCL; doesn't support as many extensions as &CMUCL;, but
121 it still has quite a few.</para>
122
123 <sect2><title>Things Which Might Be in the Next &ANSI; Standard</>
124
125 <para>&SBCL; provides extensive support for 
126 calling external C code, described 
127 <link linkend="ffi">in its own chapter</link>.</para>
128
129 <para>&SBCL; provides additional garbage collection functionality not
130 specified by &ANSI;. Weak pointers allow references to objects to be
131 maintained without keeping them from being GCed. And "finalization"
132 hooks are available to cause code to be executed when an object is
133 GCed.</para> <!-- FIXME: Actually documenting these would be good.:-| -->
134
135 <para>&SBCL; does not currently provide Gray streams, but may do so in
136 the near future. (It has unmaintained code inherited from &CMUCL; to
137 do so.) <!-- FIXME: Add citation to Gray streams.-->
138 </para>
139
140 </sect2>
141
142 <sect2><title>Support for Unix</>
143
144 <para>The UNIX command line can be read from the variable
145 <varname>sb-ext:*posix-argv*</>. The UNIX environment can be queried with the
146 <function>sb-ext:posix-getenv</> function.</para>
147
148 <para>The &SBCL; system can be terminated with <function>sb-ext:quit</>,
149 optionally returning a specified numeric value to the calling Unix
150 process. The normal Unix idiom of terminating on end of file on input
151 is also supported.</para>
152
153 </sect2>
154
155 <sect2><title>Tools to Help Developers</title>
156
157 <para>&SBCL; provides a profiler and other extensions to the &ANSI;
158 <function>trace</> facility. See the online function documentation for
159 <function>trace</> for more information.</para>
160
161 <para>The debugger supports a number of options. Its documentation is
162 accessed by typing <userinput>help</> at the debugger prompt.</para>
163 <!-- FIXME:
164      A true debugger section in the manual would be good. Start
165      with CMU CL's debugger section, but remember:
166        * no QUIT command (TOPLEVEL restart instead)
167        * no GO command (CONTINUE restart instead)
168        * Limitations of the x86 port of the debugger should be 
169          documented or fixed where possible.
170        * Discuss TRACE and its unification with PROFILE. -->
171
172 <para>Documentation for <function>inspect</> is accessed by typing
173 <userinput>help</> at the <function>inspect</> prompt.</para>
174
175 </sect2>
176
177 <sect2><title>Interface to Low-Level &SBCL; Implementation</title>
178
179 <para>&SBCL; has the ability to save its state as a file for later
180 execution. This functionality is important for its bootstrapping
181 process, and is also provided as an extension to the user See the
182 documentation for <function>sb-ext:save-lisp-and-die</> for more
183 information.</para>
184
185 <note><para>&SBCL; has inherited from &CMUCL; various hooks to allow
186 the user to tweak and monitor the garbage collection process. These
187 are somewhat stale code, and their interface might need to be cleaned
188 up. If you have urgent need of them, look at the code in
189 <filename>src/code/gc.lisp</filename> and bring it up on the
190 developers' mailing list.</para></note>
191
192 <note><para>&SBCL; has various hooks inherited from &CMUCL;, like
193 <function>sb-ext:float-denormalized-p</>, to allow a program to take
194 advantage of &IEEE; floating point arithmetic properties which aren't
195 conveniently or efficiently expressible using the &ANSI; standard. These
196 look good, and their interface looks good, but &IEEE; support is
197 slightly broken due to a stupid decision to remove some support for
198 infinities (because it wasn't in the &ANSI; spec and it didn't occur to
199 me that it was in the &IEEE; spec). If you need this stuff, take a look
200 at the ecode and bring it up on the developers' mailing
201 list.</para></note>
202
203 </sect2>
204
205 <sect2><title>Efficiency Hacks</title>
206
207 <para>The <function>sb-ext:purify</function> function causes &SBCL;
208 first to collect all garbage, then to mark all uncollected objects as
209 permanent, never again attempting to collect them as garbage. (This
210 can cause a large increase in efficiency when using a primitive
211 garbage collector, but is less important with modern generational
212 garbage collectors.)</para>
213
214 <para>The <function>sb-ext:truly-the</> operator does what the
215 <function>cl:the</> operator does in a more conventional
216 implementation of &CommonLisp;, declaring the type of its argument
217 without any runtime checks. (Ordinarily in &SBCL;, any type declaration
218 is treated as an assertion and checked at runtime.)</para>
219
220 <para>The <function>sb-ext:freeze-type</> declaration declares that a
221 type will never change, which can make type testing
222 (<function>typep</>, etc.) more efficient for structure types.</para>
223
224 <para>The <function>sb-ext:constant-function</> declaration specifies
225 that a function will always return the same value for the same
226 arguments. This is appropriate for functions like <function>sqrt</>.
227 It is not appropriate for functions like <function>aref</>, which can
228 change their return values when the underlying data are
229 changed.</para>
230
231 </sect2>
232
233 </sect1>
234
235 </chapter>