206 lines
16 KiB
HTML
206 lines
16 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 TYPE-OF-UNDERCONSTRAINED 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/iss350_w.htm">
|
|
<LINK REL=UP HREF="../Issues/iss352.htm">
|
|
<LINK REL=NEXT HREF="../Issues/iss353_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/iss350_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="../Issues/iss352.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="../Issues/iss353_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
|
|
|
|
<HR>
|
|
|
|
|
|
|
|
<H2>Issue TYPE-OF-UNDERCONSTRAINED Writeup</H2>
|
|
|
|
<PRE><B>Status:</B> passed, Jun 89 X3J13<P>
|
|
<P>
|
|
<B>Forum:</B> Cleanup<P>
|
|
<B>Issue:</B> <A HREF="iss352.htm">TYPE-OF-UNDERCONSTRAINED</A><P>
|
|
<P>
|
|
<B>References:</B> <A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> (CLtL)<P>
|
|
88-002R (Class-of)<P>
|
|
88-005, p 43f, Condition system types<P>
|
|
Related issues: <A HREF="iss335.htm">SUBTYPEP-TOO-VAGUE</A><P>
|
|
DATA-TYPE-HIERARCHY-UNDERSPECIFIED<P>
|
|
<A HREF="iss175_m.htm">FUNCTION-TYPE</A><P>
|
|
<A HREF="iss015.htm">ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS</A><P>
|
|
COERCE-INCOMPLETE<P>
|
|
<P>
|
|
<P>
|
|
<B>Category:</B> CLARIFICATION/CHANGE<P>
|
|
<P>
|
|
<B>Edit history:</B> Version 1, 1-Dec-88, Masinter<P>
|
|
Version 2, 9-Dec-88, Masinter<P>
|
|
Version 3, 12-Dec-88, Masinter (fix "egregious bug")<P>
|
|
Version 4, 3-14-89 Steele<P>
|
|
Version 5, 16-Mar-89, Masinter (add other amendments)<P>
|
|
Version 6, 22-Jun-89, Masinter (fix as per Moon)<P>
|
|
<P>
|
|
<B>Problem description:<P>
|
|
</B><P>
|
|
The specification of <A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> in CLtL is so weak as to leave it <P>
|
|
nearly useless, if any implementor actually took the specification<P>
|
|
seriously.In particular, there are almost no constraints on the<P>
|
|
value that <A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> might return for any of the built in<P>
|
|
types. The only constraint placed is that for objects created by the<P>
|
|
constructor function of <A REL=DEFINITION HREF="../Body/m_defstr.htm#defstruct"><B>DEFSTRUCT</B></A>, the result of <A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> is the name of the<P>
|
|
<A REL=DEFINITION HREF="../Body/m_defstr.htm#defstruct"><B>defstruct</B></A>.<P>
|
|
<P>
|
|
This means that implementations could return T for all other objects.<P>
|
|
<P>
|
|
<B>Proposal (TYPE-OF-UNDERCONSTRAINED:ADD-CONSTRAINTS): <P>
|
|
</B><P>
|
|
Specify that the result of <A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> satisfies the following:<P>
|
|
<P>
|
|
(a) For any object for which (<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>typep</B></A> object built-in-type) is true when<P>
|
|
built-in-type is one of <P>
|
|
<P>
|
|
<A REL=DEFINITION HREF="../Body/t_intege.htm#integer"><B>INTEGER</B></A>, <A REL=DEFINITION HREF="../Body/t_ratio.htm#ratio"><B>RATIO</B></A>, <A REL=DEFINITION HREF="../Body/a_float.htm#float"><B>FLOAT</B></A>, <A REL=DEFINITION HREF="../Body/a_comple.htm#complex"><B>COMPLEX</B></A>, <A REL=DEFINITION HREF="../Body/t_number.htm#number"><B>NUMBER</B></A>, <A REL=DEFINITION HREF="../Body/a_null.htm#null"><B>NULL</B></A>, <A REL=DEFINITION HREF="../Body/t_symbol.htm#symbol"><B>SYMBOL</B></A>, <P>
|
|
<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/a_vector.htm#vector"><B>VECTOR</B></A>, <A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A>, <A REL=DEFINITION HREF="../Body/t_rnd_st.htm#random-state"><B>RANDOM-STATE</B></A>, <A REL=DEFINITION HREF="../Body/t_seq.htm#sequence"><B>SEQUENCE</B></A>,<A REL=DEFINITION HREF="../Body/a_cons.htm#cons"><B>CONS</B></A>, <P>
|
|
<A REL=DEFINITION HREF="../Body/t_stream.htm#stream"><B>STREAM</B></A>, <A REL=DEFINITION HREF="../Body/t_pkg.htm#package"><B>PACKAGE</B></A>, <A REL=DEFINITION HREF="../Body/a_ch.htm#character"><B>CHARACTER</B></A>, <A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A>, <A REL=DEFINITION HREF="../Body/t_rdtabl.htm#readtable"><B>READTABLE</B></A>, <A REL=DEFINITION HREF="../Body/t_hash_t.htm#hash-table"><B>HASH-TABLE</B></A>, <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>PATHNAME</B></A>,<P>
|
|
<A REL=DEFINITION HREF="../Body/e_cnd.htm#condition"><B>CONDITION</B></A>, <A REL=DEFINITION HREF="../Body/t_rst.htm#restart"><B>RESTART</B></A>,<P>
|
|
<A REL=DEFINITION HREF="../Body/a_ration.htm#rational"><B>RATIONAL</B></A>, <A REL=DEFINITION HREF="../Body/t_short_.htm#short-float"><B>SHORT-FLOAT</B></A>, <A REL=DEFINITION HREF="../Body/t_short_.htm#long-float"><B>LONG-FLOAT</B></A>, <A REL=DEFINITION HREF="../Body/t_short_.htm#single-float"><B>SINGLE-FLOAT</B></A>, <A REL=DEFINITION HREF="../Body/t_short_.htm#double-float"><B>DOUBLE-FLOAT</B></A><P>
|
|
<P>
|
|
the result of <A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> will be a type specifier for which<P>
|
|
(<A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>subtypep</B></A> (<A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>type-of</B></A> object) built-in-type) returns T T, i.e., either the<P>
|
|
build-in-type or a subtype of it (a subtype that the <P>
|
|
implementation's <A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A> can recognize.)<P>
|
|
<P>
|
|
<P>
|
|
(b) For all objects, (<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> object (<A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> object)) will be true.<P>
|
|
(this implies that it will <A REL=DEFINITION HREF="../Body/a_not.htm#not"><B>not</B></A> be <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>, since no<P>
|
|
object is of <A REL=DEFINITION HREF="../Body/a_type.htm#type"><B>type</B></A> <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>.)<P>
|
|
<P>
|
|
(c) will not be T, or use <A REL=DEFINITION HREF="../Body/t_satisf.htm#satisfies"><B>SATISFIES</B></A>, <A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>AND</B></A>, <A REL=DEFINITION HREF="../Body/a_or.htm#or"><B>OR</B></A>, <A REL=DEFINITION HREF="../Body/a_not.htm#not"><B>NOT</B></A> or <A REL=DEFINITION HREF="../Body/a_values.htm#values"><B>VALUES</B></A>.<P>
|
|
<P>
|
|
(d) The type returned by <A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> is always a subtype of the <A REL=DEFINITION HREF="../Body/t_class.htm#class"><B>class</B></A><P>
|
|
returned by <A REL=DEFINITION HREF="../Body/f_clas_1.htm#class-of"><B>CLASS-OF</B></A>, and is a subtype that the implementation's<P>
|
|
<A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A> can recognize.<P>
|
|
<P>
|
|
(e) For objects of metaclass <A REL=DEFINITION HREF="../Body/t_stu_cl.htm#structure-class"><B>STRUCTURE-CLASS</B></A> or <A REL=DEFINITION HREF="../Body/t_std_cl.htm#standard-class"><B>STANDARD-CLASS</B></A>,<P>
|
|
<A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> returns the proper name of the <A REL=DEFINITION HREF="../Body/t_class.htm#class"><B>class</B></A> returned by <A REL=DEFINITION HREF="../Body/f_clas_1.htm#class-of"><B>CLASS-OF</B></A><P>
|
|
if it has a proper name, and otherwise returns the <A REL=DEFINITION HREF="../Body/t_class.htm#class"><B>class</B></A> itself.<P>
|
|
<P>
|
|
In particular, for objects created by the "constructor" function<P>
|
|
of a <A REL=DEFINITION HREF="../Body/f_docume.htm#structure"><B>structure</B></A> defined with <A REL=DEFINITION HREF="../Body/m_defstr.htm#defstruct"><B>DEFSTRUCT</B></A> without a :TYPE option,<P>
|
|
<A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> will return the <A REL=DEFINITION HREF="../Body/f_docume.htm#structure"><B>structure</B></A> name.<P>
|
|
<P>
|
|
This proposal is intended to be consistent with 88-002R, <P>
|
|
and not to conflict with any of the definitions in that document.<P>
|
|
<P>
|
|
<B>Examples:<P>
|
|
</B><P>
|
|
It is legal for (<A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> "abc") to return (<A REL=DEFINITION HREF="../Body/t_smp_st.htm#simple-string"><B>SIMPLE-STRING</B></A> 3), or just<P>
|
|
<A REL=DEFINITION HREF="../Body/a_string.htm#string"><B>STRING</B></A>. It is legal for (<A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> 112312) to return SI:MEDIUM-SIZE-FIXNUM,<P>
|
|
as long as (<A REL=DEFINITION HREF="../Body/f_subtpp.htm#subtypep"><B>SUBTYPEP</B></A> 'SI:MEDIUM-SIZE-FIXNUM '<A REL=DEFINITION HREF="../Body/t_intege.htm#integer"><B>INTEGER</B></A>).<P>
|
|
<P>
|
|
Given:<P>
|
|
<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_defpar.htm#defvar"><B>defvar</B></A> *foo* (<A REL=DEFINITION HREF="../Body/f_mk_ar.htm#make-array"><B>make-array</B></A> 5 :element-type t))<P>
|
|
(<A REL=DEFINITION HREF="../Body/f_class_.htm#class-name"><B>class-name</B></A> (<A REL=DEFINITION HREF="../Body/f_clas_1.htm#class-of"><B>class-of</B></A> *foo*)) => <A REL=DEFINITION HREF="../Body/t_smp_ve.htm#simple-vector"><B>SIMPLE-VECTOR</B></A><P>
|
|
It is legal for<P>
|
|
(<A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>type-of</B></A> *foo*) => (<A REL=DEFINITION HREF="../Body/t_smp_ve.htm#simple-vector"><B>SIMPLE-VECTOR</B></A> 5)<P>
|
|
<P>
|
|
<P>
|
|
<B>Rationale:<P>
|
|
</B><P>
|
|
The original specification for "TYPE-OF" was written to allow<P>
|
|
implementation freedom, but the wording is in fact more vague than was<P>
|
|
intended. <P>
|
|
<P>
|
|
<B>Current practice:<P>
|
|
</B><P>
|
|
Most Common Lisp implementations seem to implement the proposal, at least<P>
|
|
for the types we've tried them on.<P>
|
|
<P>
|
|
<B>Cost to Implementors:<P>
|
|
</B><P>
|
|
Even if there are implementations that do not currently implement the<P>
|
|
proposal, the required changes for them are likely to be minimal. <P>
|
|
<P>
|
|
<B>Cost to Users:<P>
|
|
</B><P>
|
|
Apparently none.<P>
|
|
<P>
|
|
<B>Cost of non-adoption:<P>
|
|
</B><P>
|
|
<A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> would remain potentially inconsistent.<P>
|
|
<P>
|
|
<B>Performance impact:<P>
|
|
</B><P>
|
|
Likely none.<P>
|
|
<P>
|
|
<B>Benefits:<P>
|
|
</B><P>
|
|
Bring the specification of <A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> in like with its common<P>
|
|
implementation, while requiring it to be generally useful.<P>
|
|
<P>
|
|
<B>Esthetics:<P>
|
|
</B><P>
|
|
Little effect.<P>
|
|
<P>
|
|
<B>Discussion:<P>
|
|
</B><P>
|
|
Originally, <A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> was concieved as being useful for information display.<P>
|
|
CLOS specified <A REL=DEFINITION HREF="../Body/f_clas_1.htm#class-of"><B>CLASS-OF</B></A> far more precisely, in that it must return exactly<P>
|
|
the <A REL=DEFINITION HREF="../Body/t_class.htm#class"><B>class</B></A> of an object. Unless <A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> is removed from the language, it<P>
|
|
seems reasonable to <A REL=DEFINITION HREF="../Body/f_provid.htm#require"><B>require</B></A> it to be at least as precise as <A REL=DEFINITION HREF="../Body/f_clas_1.htm#class-of"><B>CLASS-OF</B></A>.<P>
|
|
<P>
|
|
The accepted CLOS specification does not define <A REL=DEFINITION HREF="../Body/f_clas_1.htm#class-of"><B>CLASS-OF</B></A><P>
|
|
in terms of <A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A>, but an earlier draft did. <P>
|
|
<P>
|
|
This proposal presumes the (passed) proposals<P>
|
|
DATA-TYPES-HIERARCHY-UNDERSPECIFIED:DISJOINT, <A HREF="iss175_m.htm">FUNCTION-TYPE</A>, and<P>
|
|
accomodates the Condition System (version 18) and CLOS.<P>
|
|
<P>
|
|
If <A HREF="iss015.htm">ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS</A> does not pass, <P>
|
|
and this proposal does pass, it may be that the only way an <P>
|
|
implementation can satisfy (<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> array (<A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> array))<P>
|
|
would be to have (<A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> array) return <A REL=DEFINITION HREF="../Body/a_vector.htm#vector"><B>VECTOR</B></A> or <A REL=DEFINITION HREF="../Body/t_array.htm#array"><B>ARRAY</B></A><P>
|
|
as appropriate, i.e., with no element type qualification.<P>
|
|
<P>
|
|
It is possible to constrain <A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> further, e.g., to eliminate<P>
|
|
the possibility that it might return a non-portable <P>
|
|
implementation-specific value. For example, <P>
|
|
(<A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> 112312) should not return SI:MEDIUM-SIZE-FIXNUM, but rather some<P>
|
|
thing like (<A REL=DEFINITION HREF="../Body/t_sgn_by.htm#signed-byte"><B>SIGNED-BYTE</B></A> 17) [if that's what SI:MEDIUM-SIZE-FIXNUM means.]<P>
|
|
<P>
|
|
We would like to make this as an implementation recommendation,<P>
|
|
however, rather than as a constraint, at this point.<P>
|
|
<P>
|
|
About part (c): the restriction on T is meaningless, since the <A REL=DEFINITION HREF="../Body/f_clas_1.htm#class-of"><B>CLASS-OF</B></A><P>
|
|
restriction dominates it. The restriction on <A REL=DEFINITION HREF="../Body/a_member.htm#member"><B>MEMBER</B></A> is OK, just to keep<P>
|
|
<A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>TYPE-OF</B></A> from being the silly definition that (<A REL=DEFINITION HREF="../Body/f_tp_of.htm#type-of"><B>type-of</B></A> x) = `(member ,x). I<P>
|
|
think we're running out of good reasons to leave out <A REL=DEFINITION HREF="../Body/t_satisf.htm#satisfies"><B>SATISFIES</B></A>, <A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>AND</B></A>, <A REL=DEFINITION HREF="../Body/a_or.htm#or"><B>OR</B></A>,<P>
|
|
<A REL=DEFINITION HREF="../Body/a_not.htm#not"><B>NOT</B></A>, and VALUES; they're probably no more useful, but we're probably<P>
|
|
overspecifying for no good reason.<P>
|
|
<P>
|
|
Some types are left out of the list in (a), including:<P>
|
|
<P>
|
|
<A REL=DEFINITION HREF="../Body/t_bignum.htm#bignum"><B>BIGNUM</B></A> and <A REL=DEFINITION HREF="../Body/t_fixnum.htm#fixnum"><B>FIXNUM</B></A> were left out because their division was implementation<P>
|
|
dependent.<P>
|
|
<P>
|
|
<A REL=DEFINITION HREF="../Body/t_kwd.htm#keyword"><B>KEYWORD</B></A> was left out because under odd circumstances it is possible to<P>
|
|
dynamically change the 'type' (e.g., by <A REL=DEFINITION HREF="../Body/f_uninte.htm#unintern"><B>UNINTERN</B></A>).<P>
|
|
<P>
|
|
<A REL=DEFINITION HREF="../Body/t_std_ch.htm#standard-char"><B>STANDARD-CHAR</B></A> and STRING-CHAR were left out for the same reasons they<P>
|
|
aren't built-in classes.<P>
|
|
<P>
|
|
(These reasonas are <A REL=DEFINITION HREF="../Body/a_not.htm#not"><B>not</B></A> 100% compelling.)<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>
|