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

480 lines
41 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 ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS 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/iss014_w.htm">
<LINK REL=UP HREF="../Issues/iss015.htm">
<LINK REL=NEXT HREF="../Issues/iss016_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/iss014_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="../Issues/iss015.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="../Issues/iss016_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
<HR>
<H2>Issue ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS Writeup</H2>
<PRE><B>Status:</B> Passed, Jan 89 X3J13<P>
<P>
<B>Forum:</B> Cleanup<P>
<P>
<B>Issue:</B> <A HREF="iss015.htm">ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS</A><P>
<P>
<B>References:</B> Data types and Type specifiers: CLtL p. 11; Sect. 4.5, p.45<P>
Functions: <A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> and SUBTYPEP; CLtL Sect. 6.2.1, p.72<P>
<A REL=DEFINITION HREF="../Body/f_ar_ele.htm#array-element-type"><B>ARRAY-ELEMENT-TYPE</B></A>, CLtL p. 291<P>
The type-specifiers:<P>
<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A>, <A REL=DEFINITION HREF="../Body/t_smp_ar.htm#simple-array"><B>SIMPLE-ARRAY</B></A>, <A REL=DEFINITION HREF="../Body/a_vector.htm#vector"><B>VECTOR</B></A>, <A REL=DEFINITION HREF="../Body/t_smp_ve.htm#simple-vector"><B>SIMPLE-VECTOR</B></A><P>
<A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A><P>
<P>
Related Issues: <A HREF="iss335.htm">SUBTYPEP-TOO-VAGUE</A>, LIST-TYPE-SPECIFIER<P>
<P>
<B>Category:</B> CHANGE<P>
<P>
<B>Edit history:</B> Version 1, 13-May-88, JonL<P>
Version 2, 23-May-88, JonL <P>
(typo fixes, comments from moon, rearrange <A REL=DEFINITION HREF="../Body/f_everyc.htm#some"><B>some</B></A> discussion)<P>
Version 3, 02-Jun-88, JonL <P>
(flush alternate proposal [&quot;flush-upgrading&quot;]; consequently,<P>
move more of discussion back to discussion section.<P>
Version 4, 01-Oct-88, Jan Pedersen &amp; JonL<P>
(<A REL=DEFINITION HREF="../Body/f_reduce.htm#reduce"><B>reduce</B></A> discussion, <A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>and</B></A> &quot;cleanup&quot; wordings)<P>
(Version 5 edit history missing)<P>
Version 6, 6-Oct-88, Moon<P>
(fix typos, cover <A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>subtypep</B></A> explicitly, add <A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>complex</B></A>,<P>
change name of UPGRADE-ARRAY-ELEMENT-TYPE)<P>
Version 7, 7-Oct-88, JonL (more name <A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>and</B></A> wording changes)<P>
Version 8, 8-Oct-88, Masinter (wording, discussion)<P>
Version 9, 31-Oct-88, JonL (major re-wording to accommodate<P>
recent discussion; esp. re-introduce <A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>and</B></A> clarify &quot;upgrading&quot;)<P>
<P>
<P>
<B>Problem description:<P>
</B><P>
CLtL occasionally draws a distinction between type-specifiers &quot;for<P>
declaration&quot; and &quot;for discrimination&quot;; see CLtL, section 4.5 &quot;Type <P>
Specifiers That Specialize&quot; (p.45 and following) The phrase <P>
&quot;for declaration&quot; encompasses type-specifiers passed in as the <P>
:element-type argument to <A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>MAKE-ARRAY</B></A>, passed in as the &lt;result-type&gt; <P>
argument to <A REL=DEFINITION HREF="../Body/f_coerce.htm#coerce"><B>COERCE</B></A>, and used in <A REL=DEFINITION HREF="../Body/s_the.htm#the"><B>THE</B></A> and <A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> type declarations. The <P>
phrase &quot;for discrimination&quot; refers to the type-specifiers passed in as <P>
the &lt;type&gt; argument(s) to <A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> and <A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A>.<P>
<P>
One consequence of this distinction is that a variable declared to be of <P>
type &lt;certain-type&gt;, and all of whose assigned objects are created in <P>
accordance with that type, may still have none of its values ever satisfy <P>
the <A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> predicate with that type-specifier. One type-specifier with <P>
this property is <P>
(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> &lt;element-type&gt;) <P>
for various implementation dependent values of &lt;element-type&gt;. For<P>
example, in most implementations of CL, an array X created with an<P>
element-type of (<A REL=DEFINITION HREF="../Body/t_sgn_by.htm#signed-byte"><B>SIGNED-BYTE</B></A> 5) will, depending on the vendor, either<P>
satisfy<P>
(<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> X '(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> (<A REL=DEFINITION HREF="../Body/t_sgn_by.htm#signed-byte"><B>SIGNED-BYTE</B></A> 8))), or<P>
(<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> X '(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> T)) <P>
but (almost) never will it satisfy <P>
(<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> X '(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> (<A REL=DEFINITION HREF="../Body/t_sgn_by.htm#signed-byte"><B>SIGNED-BYTE</B></A> 5))).<P>
<P>
This is entirely permissible within the scope of standardization on<P>
<A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>MAKE-ARRAY</B></A>, where an implementation is required only to construct up the<P>
result out of &quot;the most specialized [element] type that can nevertheless<P>
accommodate elements of the given type [the :element-type argument]&quot;<P>
(see CLtL, p287). That is, an implementation may in fact only <A REL=DEFINITION HREF="../Body/f_provid.htm#provide"><B>provide</B></A> a <P>
very small number of equivalence classes of element-types for storing <P>
arrays, corresponding to its repertoire of specialized storage techniques;<P>
and it is explicitly permitted to &quot;upgrade&quot; any element-type request into <P>
one of its built-in repertoire (see also CLtL, p45, second and third<P>
paragraphs under Section 4.5.)<P>
<P>
As a practical matter, almost every existing implementation does some <P>
serious upgrading of the :element-type argument given to <A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>MAKE-ARRAY</B></A>. <P>
Yet the difference between &quot;for declaration&quot; and &quot;for discrimination&quot; <P>
has been very confusing to many people. Similarly, portability is<P>
hindered when users do not know just how a given implementation does <P>
upgrading.<P>
<P>
The type specifier (<A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A> &lt;part-type&gt;) also falls in the domain of CLtL<P>
Section 4.5. Currently, only one implementation actually provides any kind <P>
of specialized storage for complex parts; and in this case, the practical<P>
matter is less urgent, since the kind of upgrading happening is so obvious <P>
as to cause little or no confusion.<P>
<P>
<P>
Proposal: (<A HREF="iss015.htm">ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING</A>)<P>
<P>
Short Summary:<P>
<P>
<A REL=DEFINITION HREF="../Body/v__stst_.htm#STST"><B>**</B></A> Eliminate the distinction between type-specifiers &quot;for declaration&quot; and<P>
&quot;for discrimination&quot;. In short, change the meaning of array and<P>
complex type specifiers in favor of the &quot;for declaration&quot; meaning.<P>
<P>
<A REL=DEFINITION HREF="../Body/v__stst_.htm#STST"><B>**</B></A> Change the meaning of <A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> to be in accord with &quot;for declaration&quot;<P>
meaning of type-specifiers.<P>
<P>
<A REL=DEFINITION HREF="../Body/v__stst_.htm#STST"><B>**</B></A> Add an implementation-dependent function that reveals how a given <P>
type-specifier for array element-types is upgraded. Add another such <P>
function that reveals how a given type-specifier for complex parts is<P>
upgraded.<P>
<P>
<A REL=DEFINITION HREF="../Body/v__stst_.htm#STST"><B>**</B></A> Clarify that &quot;upgrading&quot; implies a movement upwards in the type-<P>
hierarchy lattice; i.e., if &lt;type&gt; upgrades to &lt;Type&gt;, then<P>
&lt;Type&gt; must be a super-type of &lt;type&gt;.<P>
<P>
<A REL=DEFINITION HREF="../Body/v__stst_.htm#STST"><B>**</B></A> Clarify that upgrading an array element-type is independent of any <P>
other property of arrays, such as rank, adjustability, fill-pointers, <P>
etc. <P>
<P>
<A REL=DEFINITION HREF="../Body/v__stst_.htm#STST"><B>**</B></A> Clarify how <A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A> thus behaves on array type-specifiers. <P>
<P>
<A REL=DEFINITION HREF="../Body/v__stst_.htm#STST"><B>**</B></A> Define how <A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A> behaves on complex type-specifiers. <P>
<P>
Note that despite this issue's name, the detailed specifications herein <P>
apply to the type system -- not to the behavior of <A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>MAKE-ARRAY</B></A>, nor to how<P>
arrays are actually implemented.<P>
<P>
Details:<P>
<P>
First, some definitions: Two type-specifiers &lt;type1&gt; and &lt;type2&gt; are said <P>
to be &quot;type-equivalent&quot; if and only if each one specifies a subtype of the<P>
other one. For example, (<A REL=DEFINITION HREF="../Body/t_unsgn_.htm#unsigned-byte"><B>UNSIGNED-BYTE</B></A> 5) and (<A REL=DEFINITION HREF="../Body/a_mod.htm#mod"><B>MOD</B></A> 32) are two different <P>
type- specifiers that always refer to the same sets of things; hence they <P>
are type-equivalent. But (<A REL=DEFINITION HREF="../Body/t_unsgn_.htm#unsigned-byte"><B>UNSIGNED-BYTE</B></A> 5) and (<A REL=DEFINITION HREF="../Body/t_sgn_by.htm#signed-byte"><B>SIGNED-BYTE</B></A> 8) are not <P>
type- equivalent since the former refers to a proper subset of the latter.<P>
Two type-specifiers &lt;type1&gt; and &lt;type2&gt; are said to be &quot;type-disjoint&quot;<P>
if their specified intersection is null. For example, <A REL=DEFINITION HREF="../Body/t_intege.htm#integer"><B>INTEGER</B></A> and <A REL=DEFINITION HREF="../Body/a_float.htm#float"><B>FLOAT</B></A> <P>
are type disjoint by definition (see CLtL p.33), and (<A REL=DEFINITION HREF="../Body/t_intege.htm#integer"><B>INTEGER</B></A> 3 5) and <P>
(<A REL=DEFINITION HREF="../Body/t_intege.htm#integer"><B>INTEGER</B></A> 7 10) are type-disjoint because the specified ranges have no<P>
elements in common.<P>
<P>
*. Eliminate the distinction between types &quot;for declaration&quot; and &quot;for <P>
discrimination&quot;. In particular, elminate any such reference in the <P>
discussion of array and complex type-specifiers; this would include <P>
documentation patterned after the discussion in section 4.5, pp. 45-7, <P>
especially the example on p.46 that says &quot;See ARRAY-ELEMENT-TYPE&quot;.<P>
Change the meaning of (<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> &lt;element-type&gt;), as well as any of the<P>
subtypes of <A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> (such as <A REL=DEFINITION HREF="../Body/t_smp_ar.htm#simple-array"><B>SIMPLE-ARRAY</B></A>, <A REL=DEFINITION HREF="../Body/a_vector.htm#vector"><B>VECTOR</B></A>, etc.) in favor of the <P>
&quot;for declaration&quot; meaning. Make the similar simplification for the <P>
&lt;part-type&gt; specifiers in the <A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A> type-specifier.<P>
<P>
*. Change the meaning of (<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> &lt;x&gt; '(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> &lt;type&gt;)), where &lt;type&gt; is not <P>
*, to be true if and only if &lt;x&gt; is an array that could be the result <P>
of giving &lt;type&gt; as the :element-type argument to <A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>MAKE-ARRAY</B></A>. While<P>
(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> *) refers to all arrays regardless of element type, (<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> &lt;type&gt;)<P>
refers only to those arrays that can result from giving &lt;type&gt; as the<P>
:element-type argument to the function <A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>MAKE-ARRAY</B></A>. Change the meanings<P>
for (<A REL=DEFINITION HREF="../Body/t_smp_ar.htm#simple-array"><B>SIMPLE-ARRAY</B></A> &lt;type&gt;) and (<A REL=DEFINITION HREF="../Body/a_vector.htm#vector"><B>VECTOR</B></A> &lt;type&gt;) in the same way.<P>
<P>
Change the meaning of (<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> &lt;x&gt; '(<A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A> &lt;type&gt;)) similarly. Thus,<P>
(<A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A> &lt;type&gt;) refers to all complex numbers that can result from <P>
giving numbers of type &lt;type&gt; to the function <A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A>, plus all other <P>
complex numbers of the same specialized representation. Remember that<P>
both the real and the imaginary parts of any such complex number must <P>
satisfy:<P>
(<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> &lt;real-or-imag-part&gt; '&lt;type&gt;). <P>
<P>
*. Add the function <A REL=DEFINITION HREF="../Body/f_upgr_1.htm#upgraded-array-element-type"><B>UPGRADED-ARRAY-ELEMENT-TYPE</B></A> of one argument, which<P>
returns the element type of the most specialized array representation<P>
capable of holding items of the given argument type. Note that except<P>
for storage allocation consequences, it could be defined as:<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> <A REL=DEFINITION HREF="../Body/f_upgr_1.htm#upgraded-array-element-type"><B>UPGRADED-ARRAY-ELEMENT-TYPE</B></A> (<A REL=DEFINITION HREF="../Body/a_type.htm#type"><B>TYPE</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/f_ar_ele.htm#array-element-type"><B>ARRAY-ELEMENT-TYPE</B></A> (<A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>MAKE-ARRAY</B></A> 0 :ELEMENT-TYPE <A REL=DEFINITION HREF="../Body/a_type.htm#type"><B>TYPE</B></A>)))<P>
<P>
Since element-type upgrading is a fundamental operation implicit in <P>
almost every existing implementation of <A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>MAKE-ARRAY</B></A>, the purpose of this <P>
added function is primarily to reveal how an implementation does its<P>
upgrading.<P>
<P>
Add the function <A REL=DEFINITION HREF="../Body/f_upgrad.htm#upgraded-complex-part-type"><B>UPGRADED-COMPLEX-PART-TYPE</B></A> of one argument that<P>
returns the part type of the most specialized complex number<P>
representation that can hold parts of the given argument type.<P>
<P>
*. Clarify that &quot;upgrading&quot; implies a movement upwards in the type-<P>
hierarchy lattice. Specifically, the type-specifier &lt;type&gt; must be<P>
a subtype of (<A REL=DEFINITION HREF="../Body/f_upgr_1.htm#upgraded-array-element-type"><B>UPGRADED-ARRAY-ELEMENT-TYPE</B></A> '&lt;type&gt;). Furthermore, if <P>
&lt;type1&gt; is a subtype of &lt;type2&gt;, then:<P>
(<A REL=DEFINITION HREF="../Body/f_upgr_1.htm#upgraded-array-element-type"><B>UPGRADED-ARRAY-ELEMENT-TYPE</B></A> '&lt;type1&gt;)<P>
must also be a subtype of:<P>
(<A REL=DEFINITION HREF="../Body/f_upgr_1.htm#upgraded-array-element-type"><B>UPGRADED-ARRAY-ELEMENT-TYPE</B></A> '&lt;type2&gt;). <P>
Note however, that two type-disjoint types can in fact be upgraded into <P>
the same thing.<P>
<P>
Clarify that <A REL=DEFINITION HREF="../Body/f_ar_ele.htm#array-element-type"><B>ARRAY-ELEMENT-TYPE</B></A> returns the upgraded element type<P>
for the array; in particular, any documentation patterned after <P>
the sentence on p. 291 begining &quot;This set may be larger than the <P>
set requested when the array was created; for example . . .&quot; should<P>
be embellished with this clarification.<P>
<P>
Similarly, the type-specifier &lt;type&gt; must be a subtype of <P>
(<A REL=DEFINITION HREF="../Body/f_upgrad.htm#upgraded-complex-part-type"><B>UPGRADED-COMPLEX-PART-TYPE</B></A> &lt;type&gt;).<P>
<P>
*. Clarify that upgrading an array element-type is independent of any <P>
other property of arrays, such as rank, adjustability, fill-pointers, <P>
displacement etc. For all such properties other than rank this should <P>
be obvious (since they are not expressible in the language of <P>
type-specifiers); but note that unless it is also independent of rank, <P>
it would not be consistently possible to displace arrays to those of <P>
differing rank.<P>
<P>
*. Clarify that <A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A> on <A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> type-specifiers is as follows: <P>
<P>
For all type-specifiers &lt;type1&gt; and &lt;type2&gt; other than *, <A REL=DEFINITION HREF="../Body/f_provid.htm#require"><B>require</B></A> <P>
(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> &lt;type1&gt;) and (<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> &lt;type2&gt;) to be type-equivalent if and only <P>
if they refer to arrays of exactly the same specialized representation; <P>
and <A REL=DEFINITION HREF="../Body/f_provid.htm#require"><B>require</B></A> them to be type-disjoint if and only if they refer to arrays <P>
of different, distinct specialized representations. This definition<P>
follows that implicitly prescribed in CLtL.<P>
<P>
As a consequence of the preceding change to <A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> and of the definition <P>
of <A REL=DEFINITION HREF="../Body/f_upgr_1.htm#upgraded-array-element-type"><B>UPGRADED-ARRAY-ELEMENT-TYPE</B></A>, the two type specifiers <P>
(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> &lt;type1&gt;) and <P>
(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> &lt;type2&gt;)<P>
are type-equivalent if and only if<P>
(<A REL=DEFINITION HREF="../Body/f_upgr_1.htm#upgraded-array-element-type"><B>UPGRADED-ARRAY-ELEMENT-TYPE</B></A> '&lt;type1&gt;) and<P>
(<A REL=DEFINITION HREF="../Body/f_upgr_1.htm#upgraded-array-element-type"><B>UPGRADED-ARRAY-ELEMENT-TYPE</B></A> '&lt;type2&gt;) <P>
are type-equivalent. This is another way of saying that `(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> &lt;type&gt;)<P>
and `(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> ,(<A REL=DEFINITION HREF="../Body/f_upgr_1.htm#upgraded-array-element-type"><B>UPGRADED-ARRAY-ELEMENT-TYPE</B></A> '&lt;type&gt;)) refer to the same<P>
set of specialized array representations.<P>
<P>
This defines the behavior of <A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A> on array type-specifiers; namely:<P>
(<A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A> '(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> &lt;type1&gt;) '(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> &lt;type2&gt;))<P>
is true if and only if<P>
(<A REL=DEFINITION HREF="../Body/f_upgr_1.htm#upgraded-array-element-type"><B>UPGRADED-ARRAY-ELEMENT-TYPE</B></A> '&lt;type1&gt;) and<P>
(<A REL=DEFINITION HREF="../Body/f_upgr_1.htm#upgraded-array-element-type"><B>UPGRADED-ARRAY-ELEMENT-TYPE</B></A> '&lt;type2&gt;)<P>
are type-equivalent.<P>
<P>
*. Define <A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A> on <A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A> type-specifiers as follows: <P>
<P>
For all type-specifiers &lt;type1&gt; and &lt;type2&gt; other than *, <P>
(<A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A> '(<A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A> &lt;type1&gt;) '(<A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A> &lt;type2&gt;))<P>
is T T if:<P>
1. &lt;type1&gt; is a subtype of &lt;type2&gt;, or<P>
2. (<A REL=DEFINITION HREF="../Body/f_upgrad.htm#upgraded-complex-part-type"><B>UPGRADED-COMPLEX-PART-TYPE</B></A> '&lt;type1&gt;) is type-equivalent<P>
to (<A REL=DEFINITION HREF="../Body/f_upgrad.htm#upgraded-complex-part-type"><B>UPGRADED-COMPLEX-PART-TYPE</B></A> '&lt;type2&gt;); in this case,<P>
(<A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A> &lt;type1&gt;) and (<A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A> &lt;type2&gt;) both refer to the <P>
same specialized representation.<P>
The result is <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> T otherwise.<P>
<P>
The small differences between the <A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A> specification for <A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> and <P>
for <A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A> are necessary because there is no creation function for <P>
complexes which allows one to specify the resultant part type independently<P>
of the actual types of the parts. Thus in the case of <A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A>, we must <P>
refer to the actual type of the parts, although a number can be a member <P>
of more than one type; e.g., 17 is of type (<A REL=DEFINITION HREF="../Body/a_mod.htm#mod"><B>MOD</B></A> 18) as well as of type<P>
(<A REL=DEFINITION HREF="../Body/a_mod.htm#mod"><B>MOD</B></A> 256); <A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>and</B></A> 2.3f5 is of <A REL=DEFINITION HREF="../Body/a_type.htm#type"><B>type</B></A> <A REL=DEFINITION HREF="../Body/t_short_.htm#single-float"><B>SINGLE-FLOAT</B></A> was well as <A REL=DEFINITION HREF="../Body/a_float.htm#float"><B>FLOAT</B></A>.<P>
The form:<P>
(<A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A> '(<A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A> <A REL=DEFINITION HREF="../Body/t_short_.htm#single-float"><B>SINGLE-FLOAT</B></A>) '(<A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A> <A REL=DEFINITION HREF="../Body/a_float.htm#float"><B>FLOAT</B></A>))<P>
must be true in all implementations; but:<P>
(<A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A> '(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> <A REL=DEFINITION HREF="../Body/t_short_.htm#single-float"><B>SINGLE-FLOAT</B></A>) '(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> <A REL=DEFINITION HREF="../Body/a_float.htm#float"><B>FLOAT</B></A>))<P>
is true only in implementations that do not have a specialized array<P>
representation for single-floats distinct from that for other floats.<P>
<P>
<P>
<B>Examples:<P>
</B><P>
Let &lt;aet-x&gt; and &lt;aet-y&gt; be two distinct type specifiers that are<P>
definitely not type-equivalent in a given implementation, but for which<P>
<A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>make-array</B></A> will return an object of the same array type. This will be<P>
an implementation dependent search, but in every implementation that<P>
the proposer has tested, there will be some such types; often,<P>
(<A REL=DEFINITION HREF="../Body/t_sgn_by.htm#signed-byte"><B>SIGNED-BYTE</B></A> 5) and (<A REL=DEFINITION HREF="../Body/t_sgn_by.htm#signed-byte"><B>SIGNED-BYTE</B></A> 8) will work.<P>
<P>
Thus, in each case, both of the following forms return T T:<P>
<P>
(<A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>subtypep</B></A> (<A REL=DEFINITION HREF="../Body/f_ar_ele.htm#array-element-type"><B>array-element-type</B></A> (<A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>make-array</B></A> 0 :element-type '&lt;aet-x&gt;))<P>
(<A REL=DEFINITION HREF="../Body/f_ar_ele.htm#array-element-type"><B>array-element-type</B></A> (<A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>make-array</B></A> 0 :element-type '&lt;aet-y&gt;)))<P>
<P>
(<A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>subtypep</B></A> (<A REL=DEFINITION HREF="../Body/f_ar_ele.htm#array-element-type"><B>array-element-type</B></A> (<A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>make-array</B></A> 0 :element-type '&lt;aet-y&gt;))<P>
(<A REL=DEFINITION HREF="../Body/f_ar_ele.htm#array-element-type"><B>array-element-type</B></A> (<A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>make-array</B></A> 0 :element-type '&lt;aet-x&gt;)))<P>
<P>
To eliminate the distinction between &quot;for declaration&quot; and &quot;for<P>
discrimination&quot; both of the following should be true:<P>
<P>
[A]<P>
(<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>typep</B></A> (<A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>make-array</B></A> 0 :element-type '&lt;aet-x&gt;)<P>
'(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>array</B></A> &lt;aet-x&gt;))<P>
(<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>typep</B></A> (<A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>make-array</B></A> 0 :element-type '&lt;aet-y&gt;)<P>
'(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>array</B></A> &lt;aet-y&gt;))<P>
<P>
Since (array &lt;aet-x&gt;) and (array &lt;aet-y&gt;) are different names for<P>
exactly the same set of objects, these names should be type-equivalent.<P>
That implies that the following set of tests should also be true:<P>
<P>
[B]<P>
(<A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>subtypep</B></A> '(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>array</B></A> &lt;aet-x&gt;) '(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>array</B></A> &lt;aet-y&gt;))<P>
(<A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>subtypep</B></A> '(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>array</B></A> &lt;aet-y&gt;) '(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>array</B></A> &lt;aet-x&gt;))<P>
<P>
Additionally, to show that un-equivalent type-specifiers that use the<P>
same specialized array type should be equivalent as element-type<P>
specifiers, the following type tests should be true:<P>
<P>
[C]<P>
(<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>typep</B></A> (<A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>make-array</B></A> 0 :element-type '&lt;aet-y&gt;)<P>
'(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>array</B></A> &lt;aet-x&gt;))<P>
(<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>typep</B></A> (<A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>make-array</B></A> 0 :element-type '&lt;aet-x&gt;)<P>
'(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>array</B></A> &lt;aet-y&gt;))<P>
<P>
<P>
<B>Rationale:<P>
</B><P>
This proposal legitimizes current practice, and removes the obscure and<P>
un-useful distinction between type-specifiers &quot;for declaration&quot; and<P>
&quot;for discrimination&quot;. The suggested changes to the interpretation of<P>
array and complex type-specifiers follow from defining type-specifiers<P>
as names for collections of objects, on <A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> being a set membership<P>
test, and <A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A> a subset test on collections of objects.<P>
<P>
<P>
<B>Current Practice:<P>
</B><P>
Every vendor's implementation that the proposer has queried has a finite <P>
set of specialized array representations, such that two non-equivalent <P>
element types can be found that use the same specialized array <P>
representation; this includes Lucid, Vaxlisp, Symbolics, TI, Franz,<P>
and Xerox. Most implementations fail tests [A] and [C] part 1, but pass<P>
tests [A] and [C] part 2; this is a consequence of implementing the<P>
distinction between &quot;for declaration&quot; and &quot;for discrimination&quot;. Lucid<P>
and Xerox both pass test [B], and the other implementations fail it.<P>
The Explorer returns <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> for all six tests in [A], [B], and [C].<P>
<P>
Allegedly, the PCLS implementation does no &quot;upgrading&quot;; each array<P>
&quot;remembers&quot; exactly the type-specifier handed to the <A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>MAKE-ARRAY</B></A> call<P>
that created it. Thus the test cases are not applicable to PCLS,<P>
since the precondition cannot be met (i.e., find two non-type-equivalent<P>
type-specifiers that are non-trivially upgraded by <A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>make-array</B></A>).<P>
<P>
The TI Explorer offers specialized representation for complexes;<P>
part types of <A REL=DEFINITION HREF="../Body/t_short_.htm#single-float"><B>SINGLE-FLOAT</B></A> and <A REL=DEFINITION HREF="../Body/t_short_.htm#double-float"><B>DOUBLE-FLOAT</B></A> are specialized.<P>
<P>
<B>Cost to Implementors:<P>
</B><P>
This proposal is an incompatible change to the current language<P>
specification, but only a small amount of work should be required in<P>
each vendor's implementation of <A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> and <A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A>.<P>
<P>
<B>Cost to Users:<P>
</B><P>
Because of the prevalence of confusion in this area, it seems unlikely<P>
that any user code will have to be changed. In fact, it is more likely<P>
that some of the vendors will cease to get bug reports about <A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>MAKE-ARRAY</B></A><P>
returning a result that isn't of &quot;the obvious type&quot;. Since the change<P>
is incompatible, some user code might have to be changed.<P>
<P>
<P>
<B>Cost of non-adoption:<P>
</B><P>
Continuing confusion in the user community.<P>
<P>
<P>
<B>Benefits:<P>
</B><P>
It will greatly reduce confusion in the user community. The fact that<P>
(<A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>MAKE-ARRAY</B></A> &lt;n&gt; :ELEMENT-TYPE '&lt;type&gt;) frequently is not of type <P>
(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> &lt;type&gt;) has been very confusing to almost everyone. <P>
<P>
Portability of applications will be increased slightly, since<P>
the behavior of <P>
(<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> (<A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>MAKE-ARRAY</B></A> &lt;n&gt; :ELEMENT-TYPE &lt;type&gt;) '(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> &lt;type&gt;))<P>
will no longer be implementation-dependent. <P>
<P>
<P>
<B>Esthetics:<P>
</B><P>
Reducing the confusing distinction between type-specifiers &quot;for<P>
declaration&quot; and &quot;for discrimination&quot; is a simplifying step -- it is a<P>
much simpler rule to state that the type-specifiers actually describe<P>
the collections of data they purport to name. Thus this is a step<P>
towards increased elegance.<P>
<P>
<P>
<B>Discussion:<P>
</B><P>
This issue was prompted by a lengthy discussion on the Common Lisp<P>
mailing list. See for example a series of exchanges started on Thu, <P>
17 Dec 87 10:48:05 PST by Jeff Barnett &lt;jbarnett@nrtc.northrop.com&gt;<P>
under the subject line of &quot;Types in CL&quot;. See also the exchange started <P>
Wed, 6 Jan 88 23:21:16 PST by Jon L White &lt;edsel!jonl@labrea.stanford.edu&gt;<P>
under the subject line of &quot;TYPEP warp implications&quot;<P>
<P>
Although the types <A REL=DEFINITION HREF="../Body/a_string.htm#string"><B>STRING</B></A>, <A REL=DEFINITION HREF="../Body/t_bt_vec.htm#bit-vector"><B>BIT-VECTOR</B></A>, <A REL=DEFINITION HREF="../Body/t_smp_st.htm#simple-string"><B>SIMPLE-STRING</B></A>, and <P>
<A REL=DEFINITION HREF="../Body/t_smp_bt.htm#simple-bit-vector"><B>SIMPLE-BIT-VECTOR</B></A> are subtypes of the <A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> type, they are not<P>
specifically discussed in this proposal. The reason is that <P>
they are not type-specifiers &quot;that specialize&quot;, but are merely <P>
abbreviations as follows:<P>
<A REL=DEFINITION HREF="../Body/a_string.htm#string"><B>STRING</B></A> == (<A REL=DEFINITION HREF="../Body/a_vector.htm#vector"><B>VECTOR</B></A> STRING-CHAR)<P>
<A REL=DEFINITION HREF="../Body/t_smp_st.htm#simple-string"><B>SIMPLE-STRING</B></A> == (<A REL=DEFINITION HREF="../Body/t_smp_ar.htm#simple-array"><B>SIMPLE-ARRAY</B></A> STRING-CHAR (*))<P>
<A REL=DEFINITION HREF="../Body/t_bt_vec.htm#bit-vector"><B>BIT-VECTOR</B></A> == (<A REL=DEFINITION HREF="../Body/a_vector.htm#vector"><B>VECTOR</B></A> <A REL=DEFINITION HREF="../Body/a_bit.htm#bit"><B>BIT</B></A>)<P>
<A REL=DEFINITION HREF="../Body/t_smp_bt.htm#simple-bit-vector"><B>SIMPLE-BIT-VECTOR</B></A> == (<A REL=DEFINITION HREF="../Body/t_smp_ar.htm#simple-array"><B>SIMPLE-ARRAY</B></A> <A REL=DEFINITION HREF="../Body/a_bit.htm#bit"><B>BIT</B></A> (*))<P>
Thus their semantics could be affected only in an implementation that<P>
doesn't support a specific &quot;specialized storage&quot; type for arrays of<P>
bits and vectors of string-chars. But in fact, every CL implementation <P>
must appear to support &quot;specialized storage&quot; for bit-arrays and strings,<P>
even if it means nothing more than remembering the fact that such an<P>
array was created with that element-type. This is required in order<P>
for strings, bit-vectors, and bit-arrays to be disjoint datatypes <P>
(see CLtL p.34; see also <A REL=DEFINITION HREF="../Body/s_the.htm#the"><B>the</B></A> definitions of BIT-ARRAY <A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>and</B></A> <A REL=DEFINITION HREF="../Body/a_string.htm#string"><B>STRING</B></A> found <P>
in CLtL p.293, Section 17.4, <A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>and</B></A> in CLtL p.299.)<P>
<P>
We considered the possibility of flushing the permission to &quot;upgrade&quot;;<P>
for example, it could be made a requirement that:<P>
(<A REL=DEFINITION HREF="../Body/f_ar_ele.htm#array-element-type"><B>ARRAY-ELEMENT-TYPE</B></A> (<A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>MAKE-ARRAY</B></A> &lt;n&gt; :ELEMENT-TYPE &lt;type&gt;))<P>
always be equal to &lt;type&gt; (or, at least type-equivalent to &lt;type&gt;)<P>
for all valid type specifiers &lt;type&gt;. This has several problems: it<P>
increases the storage requirement for many kinds of arrays, and hides<P>
a relevant part of the underlying implementation for no apparently <P>
good reason. However, it would increase portability, since it would be <P>
much more difficult, for example, to write a program that created an<P>
array with one element-type, say, (<A REL=DEFINITION HREF="../Body/t_unsgn_.htm#unsigned-byte"><B>UNSIGNED-BYTE</B></A> 5), but operated on it <P>
assuming a non-trivial upgraded element-type, say, (<A REL=DEFINITION HREF="../Body/t_unsgn_.htm#unsigned-byte"><B>UNSIGNED-BYTE</B></A> 8).<P>
Under this proposal, it is valid for an implementation of <A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>MAKE-ARRAY</B></A> <P>
to have arrays &quot;remember&quot; the type-equivalence <A REL=DEFINITION HREF="../Body/t_class.htm#class"><B>class</B></A> of the original <P>
:element-type argument; such an implementation would satisfy all of <P>
the constraints listed above.<P>
<P>
We considered a suggestion to restrict the set of &quot;known&quot; array element <P>
types; this would gain portability at the expense of limiting the <P>
language.<P>
<P>
We considered leaving out of the proposal the addition of the two<P>
functions <A REL=DEFINITION HREF="../Body/f_upgr_1.htm#upgraded-array-element-type"><B>UPGRADED-ARRAY-ELEMENT-TYPE</B></A> and <A REL=DEFINITION HREF="../Body/f_upgrad.htm#upgraded-complex-part-type"><B>UPGRADED-COMPLEX-PART-TYPE</B></A>.<P>
But it was noted that every implementation of CL supports exactly<P>
that functionality somewhere in its implementation of MAKE-ARRAY; and<P>
exposing this to the user would be a good thing. Furthermore, the<P>
existence of at least <A REL=DEFINITION HREF="../Body/f_upgr_1.htm#upgraded-array-element-type"><B>UPGRADED-ARRAY-ELEMENT-TYPE</B></A> makes the clarifications<P>
on &quot;upgrading&quot; and <A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A> implications easier. Finally, there would<P>
be no other way at all to pinpoint just how complex parts are upgraded,<P>
since there is no type information available except for the actual<P>
types of the parts.<P>
<P>
Since this proposal contains the implication:<P>
(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> &lt;type1&gt;) is-type-equivalent-to (<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> &lt;type2&gt;)<P>
==&gt; <P>
&lt;type1&gt; is-type-equivalent-to &lt;type2&gt;<P>
then the question naturally arises &quot;Does the reverse implication hold?&quot; <P>
That is, should two non-EQ but type-equivalent type-specifiers &lt;type1&gt;<P>
and &lt;type2&gt; always give rise to the same array types? For example, <P>
consider <A REL=DEFINITION HREF="../Body/t_short_.htm#short-float"><B>SHORT-FLOAT</B></A> and <A REL=DEFINITION HREF="../Body/t_short_.htm#single-float"><B>SINGLE-FLOAT</B></A> in an implementation where these <P>
are type-equivalent (see CLtL section 2.1.3). One may desire to implement <P>
(<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> <A REL=DEFINITION HREF="../Body/t_short_.htm#short-float"><B>SHORT-FLOAT</B></A>) and (<A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A> <A REL=DEFINITION HREF="../Body/t_short_.htm#single-float"><B>SINGLE-FLOAT</B></A>) differently. Say, for example <P>
that the former is packed into 16-bit half-words, whereas the latter is <P>
packed into 32-bit words; but for either kind of packing, the result of <P>
<A REL=DEFINITION HREF="../Body/f_aref.htm#aref"><B>AREF</B></A> is an ordinary &quot;single-float&quot;. The whole point of the type-specifier<P>
to <A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>make-array</B></A> is merely to specify a packing technique for &quot;packed float&quot; <P>
arrays. This &quot;krinkle&quot;, however, will not be addressed by the proposal <P>
herein; it should simply be remembered that the implication above goes <P>
only one way, and is not an &quot;if-and-only-if&quot; link.<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>