1
0
Fork 0
cl-sites/HyperSpec-7-0/HyperSpec/Issues/iss012_w.htm
2024-04-01 10:24:07 +02:00

355 lines
22 KiB
HTML

<!-- Common Lisp HyperSpec (TM), version 7.0 generated by Kent M. Pitman on Mon, 11-Apr-2005 2:31am EDT -->
<HTML>
<HEAD>
<TITLE>CLHS: Issue ARGUMENT-MISMATCH-ERROR Writeup</TITLE>
<LINK HREF="../Data/clhs.css" REL="stylesheet" TYPE="text/css" />
<META HTTP-EQUIV="Author" CONTENT="Kent M. Pitman">
<META HTTP-EQUIV="Organization" CONTENT="LispWorks Ltd.">
<LINK REL=TOP HREF="../Front/index.htm">
<LINK REL=COPYRIGHT HREF="../Front/Help.htm#Legal">
<LINK REL=DISCLAIMER HREF="../Front/Help.htm#Disclaimer">
<LINK REL=PREV HREF="../Issues/iss011_w.htm">
<LINK REL=UP HREF="../Issues/iss012.htm">
<LINK REL=NEXT HREF="../Issues/iss013_w.htm">
</HEAD>
<BODY>
<H1><A REV=MADE HREF="http://www.lispworks.com/"><IMG WIDTH=80 HEIGHT=65 ALT="[LISPWORKS]" SRC="../Graphics/LWSmall.gif" ALIGN=Bottom></A><A REL=TOP HREF="../Front/index.htm"><IMG WIDTH=237 HEIGHT=65 ALT="[Common Lisp HyperSpec (TM)]" SRC="../Graphics/CLHS_Sm.gif" ALIGN=Bottom></A> <A REL=PREV HREF="../Issues/iss011_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="../Issues/iss012.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="../Issues/iss013_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
<HR>
<H2>Issue ARGUMENT-MISMATCH-ERROR Writeup</H2>
<PRE><B>Issue:</B> <A HREF="iss012.htm">ARGUMENT-MISMATCH-ERROR</A><P>
<B>Forum:</B> Cleanup<P>
<B>References:</B> ANSI CL spec (Aug 29, 1989 draft) pp.4-11,4-12,4-13,4-15,1-10<P>
88-002R p.1-26 (appears also on p.4-20 of ANSI CL draft) <P>
<B>Category:</B> CHANGE<P>
<B>Edit history:</B> 1-Feb-90, Version 1 by Moon<P>
9-May-90, Version 2 by Moon <P>
(address another inconsistency, found by Kim Barrett)<P>
30-Oct-90, Version 3 by Pitman <P>
(<A REL=DEFINITION HREF="../Body/f_firstc.htm#first"><B>first</B></A> attempt to formalize X3J13 amendments to v2)<P>
01-Nov-90, Version 4 by Pitman (comments by Moon, Barrett)<P>
01-Nov-90, Version 5 by Pitman (more comments by Moon, Barrett)<P>
24-Feb-91, Version 6 by Loosemore (propose more amendments)<P>
14-Mar-91, Version 7 by Loosemore (change item 11)<P>
<B>Status:</B> v2+amendments (reflected in v5) accepted by X3J13, June 1990<P>
<P>
<B>Problem description:<P>
</B> <P>
The draft ANSI Common Lisp specification is inconsistent about what kind <P>
of error handling occurs when a function is called with arguments that <P>
do not match its definition.<P>
<P>
1. For too few arguments, p.4-11 says &quot;there must be at least n passed<P>
arguments,&quot; which probably (page 1-10) means &quot;the consequences are<P>
undefined&quot; if there are too few arguments.<P>
<P>
2. For too many arguments, p.4-12 says &quot;an error of type error is <P>
signalled.&quot;<P>
<P>
3. For unrecognized keyword arguments, p.4-13 says &quot;the consequences <P>
are undefined.&quot; On the other hand, p.4-15 says &quot;and error would be<P>
signalled.&quot;<P>
<P>
4. For keyword argument names that are not symbols, p.4-13 says &quot;the<P>
consequences are undefined.&quot;<P>
<P>
5. For unrecognized keyword arguments supplied to generic functions, <P>
p.4-20 and 88-002R p.1-26 say &quot;an error is signalled.&quot;<P>
<P>
This is Symbolics issue #5.<P>
<P>
<B>Proposal (ARGUMENT-MISMATCH-ERROR:MUST-SIGNAL-WHEN-SAFE-OR-SYSTEM):<P>
</B> <P>
Define that an error must be signalled in cases 1, 2, 3, and 5 of the<P>
argument mismatch situations in the problem description if the caller,<P>
the callee, and the point of functional evaluation all appear in a<P>
context where a `safe' optimization setting is in effect (i.e., <P>
SAFETY=3). In all other scenarios for these situations, the <P>
consequences are undefined.<P>
<P>
Case 4 is treated the same, except that when :allow-other-keys t or<P>
&amp;allow-other-keys is involved, error detection is optional (i.e., the<P>
consequences are undefined if the keyword argument names are not symbols).<P>
<P>
If any of the caller, the callee, or the point of functional evaluation<P>
was not user code, and was instead supplied by the implementation as a<P>
pre-defined definition, or as automatically generated code (e.g., as<P>
in <A REL=DEFINITION HREF="../Body/t_method.htm#method"><B>method</B></A> combination), then it must be treated as safe unless some <P>
user code involved in the scenario is not safe.<P>
<P>
Clarify that a reference to the symbolic name of the function or to the <P>
contents of the <A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>symbol-function</B></A> of a symbol does not count as a functional<P>
evaluation. For the purposes of this definition, functional evaluation<P>
occurs either explicitly due to a use of the <A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> special form, or <P>
implicitly due to the use of a function name in the <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> of a normal<P>
functional form.<P>
<P>
The naive model which is intended is that the user can rely on error <P>
checking in these situations if he has taken all reasonable steps to<P>
ensure that the situations will be safe.<P>
<P>
The exact time that the error will be signalled is implementation-dependent,<P>
but will always be prior to the execution of the body of the function being<P>
called.<P>
<P>
<B>Clarifications:<P>
</B><P>
The error might be signalled at compile time or at run time. If the<P>
error is signalled at run time, it might be signalled by either the<P>
caller or the callee.<P>
<P>
The reason that this terminology is used, and not the normal, &quot;should<P>
signal&quot; terminology is because system code may be involved, and the<P>
user may not know in general whether system code was compiled `safe'<P>
or `unsafe'. An implication of this definition is that all code<P>
compiled by the system will behave as if compiled safe unless some<P>
user code involved in the scenario is not. So, for example, if a user<P>
calls <A REL=DEFINITION HREF="../Body/f_mapc_.htm#mapcar"><B>MAPCAR</B></A> from safe code and passes a function which was compiled<P>
safe, the system is required to ensure that <A REL=DEFINITION HREF="../Body/f_mapc_.htm#mapcar"><B>MAPCAR</B></A> will make a safe<P>
call as well.<P>
<P>
<P>
<B>Proposal (ARGUMENT-MISMATCH-ERROR:MORE-CLARIFICATIONS):<P>
</B><P>
Amend proposal MUST-SIGNAL-WHEN-SAFE-OR-SYSTEM as follows:<P>
<P>
(1) Clarify that if the callee is a generic function, the generic function<P>
definition (if it was defined explicitly), the <A REL=DEFINITION HREF="../Body/t_method.htm#method"><B>method</B></A> definitions for <P>
all applicable methods, and the <A REL=DEFINITION HREF="../Body/a_method.htm#method-combination"><B>method-combination</B></A> definition must all<P>
be safe for the callee to be considered safe.<P>
<P>
(2) Clarify that for a form (<A REL=DEFINITION HREF="../Body/f_coerce.htm#coerce"><B>COERCE</B></A> &lt;lambda-expression&gt; '<A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A>),<P>
the value of the <A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>OPTIMIZE</B></A> <A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>SAFETY</B></A> quality in the global environment<P>
at the time the <A REL=DEFINITION HREF="../Body/f_coerce.htm#coerce"><B>COERCE</B></A> is executed applies to the resulting function.<P>
<P>
(3) Clarify that for a form (ENCLOSE &lt;lambda-expression&gt; &lt;environment&gt;),<P>
the value of the <A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>OPTIMIZE</B></A> <A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>SAFETY</B></A> quality in the &lt;environment&gt; <P>
argument applies to the resulting function.<P>
<P>
(4) Clarify that for <A REL=DEFINITION HREF="../Body/t_generi.htm#generic-function"><B>GENERIC-FUNCTION</B></A>, GENERIC-FLET, and GENERIC-LABELS<P>
forms, the value of the <A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>OPTIMIZE</B></A> <A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>SAFETY</B></A> quality in the environment <P>
in which the form appears applies to the resulting generic functions <P>
and <A REL=DEFINITION HREF="../Body/t_method.htm#method"><B>method</B></A> definitions.<P>
<P>
(5) Clarify that for a form (<A REL=DEFINITION HREF="../Body/f_ensure.htm#ensure-generic-function"><B>ENSURE-GENERIC-FUNCTION</B></A> . arguments), the<P>
value of the <A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>OPTIMIZE</B></A> <A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>SAFETY</B></A> quality in the environment passed as<P>
the :environment keyword applies to the resulting generic function.<P>
<P>
(6) Clarify that for a form (<A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A> &lt;name&gt; &lt;lambda-expression&gt;), the<P>
value of the <A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>OPTIMIZE</B></A> <A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>SAFETY</B></A> quality in the global environment at<P>
the time the <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A> is executed applies to the resulting <P>
compiled function.<P>
<P>
(7) Clarify that for a form (<A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A> &lt;name&gt;), if the original definition<P>
of the function was at a `safe' optimization setting, then the<P>
resulting compiled function must also be `safe'.<P>
<P>
Rationale: although many implementations do not save the information<P>
about the global environment for interpreted functions, this is<P>
consistent with the idea that safety is a lexical property that is<P>
captured at the time code promotion occurs. Implementations that do<P>
not save the necessary information must treat interpreted functions<P>
as being always &quot;safe&quot;.<P>
<P>
(8) Clarify that &quot;automatically generated code&quot; does not apply to the<P>
expansions of macros defined in the <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A>, which inherit safety<P>
from the environment in which the macro call appears.<P>
<P>
Rationale: this term isn't very well defined. <P>
<P>
(9) Replace the words &quot;supplied by the implementation as a pre-defined<P>
definition&quot; with &quot;supplied by the implementation and part of the<P>
Common Lisp standard&quot;.<P>
<P>
Rationale: the original wording prohibits implementations from<P>
providing *any* functions that do no argument checking, even<P>
internal functions that users might accidentally get their hands on<P>
as well as officially supported extensions. There's no good <P>
reason to prohibit this, since presumably users have to ask for <P>
these unsafe functions explicitly.<P>
<P>
(10) Clarify that a call to a <A REL=DEFINITION HREF="../Body/t_method.htm#method"><B>method</B></A> via <A REL=DEFINITION HREF="../Body/f_call_n.htm#call-next-method"><B>CALL-NEXT-METHOD</B></A> must be <P>
considered `safe' if the generic function, applicable methods,<P>
<A REL=DEFINITION HREF="../Body/a_method.htm#method-combination"><B>method-combination</B></A>, and the definition and efunctuation of the<P>
<A REL=DEFINITION HREF="../Body/f_call_n.htm#call-next-method"><B>CALL-NEXT-METHOD</B></A> itself are all `safe'.<P>
<P>
(11) Specify that if <A REL=DEFINITION HREF="../Body/f_call_n.htm#call-next-method"><B>CALL-NEXT-METHOD</B></A> is called with arguments, the ordered<P>
set of applicable methods for the changed set of arguments for<P>
<A REL=DEFINITION HREF="../Body/f_call_n.htm#call-next-method"><B>CALL-NEXT-METHOD</B></A> must be the same as the ordered set of applicable<P>
methods for the original arguments to the generic function, or an error<P>
should be signaled. [This is a change -- 88-002R p2-13 says this<P>
situation must always be detected.]<P>
<P>
Clarify that the comparison between the set of methods applicable to the<P>
new arguments and the set applicable to the original arguments is<P>
insensitive to order differences among methods with the same<P>
specializers.<P>
<P>
(12) Clarify that if <A REL=DEFINITION HREF="../Body/f_call_n.htm#call-next-method"><B>CALL-NEXT-METHOD</B></A> is called with arguments that specify<P>
a different ordered set of applicable methods and there is no next<P>
<A REL=DEFINITION HREF="../Body/t_method.htm#method"><B>method</B></A> available, the test for different methods and the associated<P>
error signalling (when present) takes precedence over calling<P>
<A REL=DEFINITION HREF="../Body/f_no_nex.htm#no-next-method"><B>NO-NEXT-METHOD</B></A>.<P>
<P>
<P>
<B>Examples:<P>
</B><P>
A. Given ...<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_declai.htm#declaim"><B>declaim</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>optimize</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>safety</B></A> 3)))<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>defun</B></A> foo (x) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>print</B></A> 'test-failed) x)<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>defun</B></A> bar (<A REL=DEFINITION HREF="../Body/03_da.htm#AMkey"><B>&amp;key</B></A> x) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>print</B></A> 'test-failed) x)<P>
(<A REL=DEFINITION HREF="../Body/m_defmet.htm#defmethod"><B>defmethod</B></A> baz ((a <A REL=DEFINITION HREF="../Body/t_intege.htm#integer"><B>integer</B></A>) <A REL=DEFINITION HREF="../Body/03_da.htm#AMkey"><B>&amp;key</B></A> x) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>print</B></A> 'test-failed) x)<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>defun</B></A> funcall-it (x) (<A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>funcall</B></A> x))<P>
<P>
Then every implementation must arrange for an error to be signalled<P>
no later than the body (i.e., before (print 'test-failed) is executed)<P>
if the following forms also occur in safe code:<P>
<P>
A.1: (foo)<P>
A.2: (foo 1 2)<P>
A.3: (bar :y 1)<P>
A.4: (bar 1 2)<P>
A.5: (baz 1 :y 7)<P>
A.6: (<A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>funcall</B></A> #'foo)<P>
A.7: (<A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>funcall</B></A> 'foo)<P>
A.8: (<A REL=DEFINITION HREF="../Body/f_mapc_.htm#mapcar"><B>mapcar</B></A> #'foo '(1 2) '(1 2))<P>
A.9: (<A REL=DEFINITION HREF="../Body/f_mapc_.htm#mapcar"><B>mapcar</B></A> 'foo '(1 2) '(1 2))<P>
A.8: (<A REL=DEFINITION HREF="../Body/f_mapc_.htm#mapcar"><B>mapcar</B></A> #'<A REL=DEFINITION HREF="../Body/f_1pl_1_.htm#1PL"><B>1+</B></A> '(1 2) '(1 2))<P>
A.9: (<A REL=DEFINITION HREF="../Body/f_mapc_.htm#mapcar"><B>mapcar</B></A> '<A REL=DEFINITION HREF="../Body/f_1pl_1_.htm#1PL"><B>1+</B></A> '(1 2) '(1 2))<P>
A.10: (funcall-it #'foo)<P>
A.10: (funcall-it 'foo)<P>
A.11: (funcall-it #'<A REL=DEFINITION HREF="../Body/f_1pl_1_.htm#1PL"><B>1+</B></A>)<P>
A.12: (funcall-it '<A REL=DEFINITION HREF="../Body/f_1pl_1_.htm#1PL"><B>1+</B></A>)<P>
A.13: (let ((x (locally (declare (optimize (safety 0))) 'foo)))<P>
(funcall-it x))<P>
A.14: (let ((x (locally (declare (optimize (safety 0))) '<A REL=DEFINITION HREF="../Body/f_1pl_1_.htm#1PL"><B>1+</B></A>)))<P>
(funcall-it x))<P>
A.15: (let ((x (locally (declare (optimize (safety 0)))<P>
(<A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>symbol-function</B></A> 'foo))))<P>
(funcall-it x))<P>
A.16: (let ((x (locally (declare (optimize (safety 0)))<P>
(<A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>symbol-function</B></A> '<A REL=DEFINITION HREF="../Body/f_1pl_1_.htm#1PL"><B>1+</B></A>))))<P>
(funcall-it x))<P>
<P>
B. Here are some examples of situations that might signal an error, but <P>
are not required to signal an error. In effect, the consequences are<P>
undefined in these cases, even if the surrounding code is declared safe:<P>
<P>
;; Functional evaluation is not safe:<P>
B.1: (let ((x (locally (declare (optimize (safety 2))) #'foo)))<P>
(funcall-it x))<P>
B.2: (let ((x (locally (declare (optimize (safety 2))) #'<A REL=DEFINITION HREF="../Body/f_1pl_1_.htm#1PL"><B>1+</B></A>)))<P>
(funcall-it x))<P>
<P>
;; Point of call is not safe:<P>
B.3: (let ((x #'foo))<P>
(<A REL=DEFINITION HREF="../Body/s_locall.htm#locally"><B>locally</B></A> (<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>declare</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>optimize</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>safety</B></A> 2)))<P>
(<A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>funcall</B></A> x)))<P>
B.4: (let ((x #'<A REL=DEFINITION HREF="../Body/f_1pl_1_.htm#1PL"><B>1+</B></A>))<P>
(<A REL=DEFINITION HREF="../Body/s_locall.htm#locally"><B>locally</B></A> (<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>declare</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>optimize</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>safety</B></A> 2)))<P>
(<A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>funcall</B></A> x)))<P>
<P>
;; Callee is not safe:<P>
(<A REL=DEFINITION HREF="../Body/s_locall.htm#locally"><B>locally</B></A> (<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>declare</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>optimize</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>safety</B></A> 2)))<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>defun</B></A> foo1 (x) x))<P>
B.5: (foo1)<P>
B.6: (<A REL=DEFINITION HREF="../Body/f_mapc_.htm#mapcar"><B>mapcar</B></A> #'foo1 '(1 2) '(1 2))<P>
B.6: (funcall-it 'foo1)<P>
<P>
<B>Rationale:<P>
</B> <P>
It's important for the document to be consistent and always say the<P>
same thing about each individual error situation. It also seems<P>
important for the five error situations to be treated equally.<P>
<P>
Further, it's important that programmers be able to debug their code<P>
conveniently in a safe environment. Once they start tampering with<P>
safety, they may run immediately into situations that expose<P>
variations in how implementations deal with function calling, but<P>
where safety is uniformly requested by the code, they should be able<P>
to insulate themselves from such differences.<P>
<P>
An exception is made in the name of efficiency for case 4 when<P>
:ALLOW-OTHER-KEYS T or <A REL=DEFINITION HREF="../Body/03_da.htm#AMallow-other-keys"><B>&amp;ALLOW-OTHER-KEYS</B></A> is used.<P>
<P>
<B>Current practice:<P>
</B><P>
CLtL did not <A REL=DEFINITION HREF="../Body/f_provid.htm#require"><B>require</B></A> this level of error checking, so it's entirely <P>
likely that there are implementations which do not conform.<P>
<P>
Symbolics Genera conforms to this proposal.<P>
<P>
<B>Cost to Implementors:<P>
</B><P>
Some implementations already implement most or all of this, so their<P>
cost will be minimal.<P>
<P>
A few implementations may not implement this. The cost will vary<P>
depending on the implementation. In some cases, it could take a fairly<P>
substantial amount of work to make these changes.<P>
<P>
An implementation not willing to make these changes might prefer to<P>
identify itself as implementing only a low-safety subset of the<P>
language, and simply refuse to compile code which was declared high<P>
safety. This might be appropriate for certain delivery situations.<P>
<P>
<B>Cost to Users:<P>
</B><P>
More robust code.<P>
<P>
<B>Cost of non-adoption:<P>
</B><P>
The specification document will not even be self-consistent.<P>
<P>
<B>Performance impact:<P>
</B><P>
None.<P>
<P>
<B>Benefits:<P>
</B><P>
Language consistency.<P>
<P>
<B>Aesthetics:<P>
</B><P>
This is an improvement over the inconsistent situation which preceded it.<P>
<P>
<B>Discussion:<P>
</B><P>
The idea of making this merely &quot;undefined&quot; was discussed and rejected<P>
at the June 1990 meeting. There was consensus that signalling an<P>
error was fine, but the main sticking points were saying under what<P>
situations the user could depend on such signalling, and at what time<P>
the signalling might be permitted to occur. The following `amendment'<P>
to the previous proposal was proposed and adopted, with the intent<P>
that it be clarified later:<P>
<P>
&quot;should signal&quot;<P>
+<P>
[ efunctuation ]<P>
[ caller ] [ system or safe ]<P>
[ callee ]<P>
+<P>
&quot;and no later than the body of the callee&quot;<P>
<P>
Versions 3-5 were an attempt to clarify what was voted upon.<P>
<P>
Version 6 is an attempt to fix some lingering problems in the<P>
writeup from version 5, mostly related to other situations in which<P>
function promotion can occur that were not dealt with explicitly<P>
in version 5.<P>
<P>
</PRE>
<HR>
<A REL=NAVIGATOR HREF="../Front/StartPts.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Starting Points]" SRC="../Graphics/StartPts.gif" ALIGN=Bottom></A><A REL=TOC HREF="../Front/Contents.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Contents]" SRC="../Graphics/Contents.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Master.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Index]" SRC="../Graphics/Index.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Symbol.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Symbols]" SRC="../Graphics/Symbols.gif" ALIGN=Bottom></A><A REL=GLOSSARY HREF="../Body/26_a.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Glossary]" SRC="../Graphics/Glossary.gif" ALIGN=Bottom></A><A HREF="../Front/X3J13Iss.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Issues]" SRC="../Graphics/Issues.gif" ALIGN=Bottom></A><BR>
<A REL=COPYRIGHT HREF="../Front/Help.htm#Legal"><I>Copyright 1996-2005, LispWorks Ltd. All rights reserved.</I></A><P>
</BODY>
</HTML>