1
0
Fork 0
cl-sites/HyperSpec-7-0/HyperSpec/Issues/iss291_w.htm

192 lines
12 KiB
HTML
Raw Normal View History

2024-04-01 10:24:07 +02:00
<!-- 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 RECURSIVE-DEFTYPE 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/iss290_w.htm">
<LINK REL=UP HREF="../Issues/iss291.htm">
<LINK REL=NEXT HREF="../Issues/iss292_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/iss290_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="../Issues/iss291.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="../Issues/iss292_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
<HR>
<H2>Issue RECURSIVE-DEFTYPE Writeup</H2>
<PRE><B>Issue:</B> <A HREF="iss291.htm">RECURSIVE-DEFTYPE</A><P>
<B>Forum:</B> Editorial<P>
<B>References:</B> <A REL=DEFINITION HREF="../Body/m_deftp.htm#deftype"><B>DEFTYPE</B></A> (p50)<P>
<B>Category:</B> CLARIFICATION<P>
<B>Edit history:</B> 05-Mar-91, Version 1 by Pitman<P>
15-Mar-91, Version 2 by Pitman, Loosemore<P>
(expand scope of proposal to treat both program and<P>
structural circularities, and to treat both macros<P>
and type specifiers equivalently)<P>
<B>Status:</B> For X3J13 consideration<P>
<P>
<B>Problem Description:<P>
</B><P>
In discussion of issue <A HREF="iss078.htm">CONS-TYPE-SPECIFIER</A>, it became apparent that some<P>
users thought it might be ok to have non-terminating recursive <A REL=DEFINITION HREF="../Body/m_deftp.htm#deftype"><B>DEFTYPE</B></A><P>
definitions. Some vendors balked at this. The case in question, which<P>
is not [yet] valid Common Lisp at the time the proposal is written, but <P>
which nevertheless illustrates the point, is Barry Margolin's:<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_deftp.htm#deftype"><B>deftype</B></A> proper-list (<A REL=DEFINITION HREF="../Body/03_da.htm#AMoptional"><B>&amp;optional</B></A> (element-type t))<P>
`(<A REL=DEFINITION HREF="../Body/a_or.htm#or"><B>or</B></A> <A REL=DEFINITION HREF="../Body/a_null.htm#null"><B>null</B></A> (<A REL=DEFINITION HREF="../Body/a_cons.htm#cons"><B>cons</B></A> ,element-type proper-list)))<P>
<P>
Another case, which is also not valid Common Lisp but which illustrates<P>
a case that might be more tolerable is Allan Wechsler's:<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_deftp.htm#deftype"><B>deftype</B></A> list-of-length (<A REL=DEFINITION HREF="../Body/f_length.htm#length"><B>length</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/s_if.htm#if"><B>if</B></A> (= 0 <A REL=DEFINITION HREF="../Body/f_length.htm#length"><B>length</B></A>)<P>
'<A REL=DEFINITION HREF="../Body/a_null.htm#null"><B>null</B></A><P>
`(<A REL=DEFINITION HREF="../Body/a_cons.htm#cons"><B>cons</B></A> t (list-of-length ,(- <A REL=DEFINITION HREF="../Body/f_length.htm#length"><B>length</B></A> 1)))))<P>
<P>
<B>Proposal (RECURSIVE-DEFTYPE:EXPLICITLY-VAGUE):<P>
</B><P>
Clarify that recursive expansion of the type specifier returned as<P>
the expansion of a <A REL=DEFINITION HREF="../Body/m_deftp.htm#deftype"><B>DEFTYPE</B></A> must terminate, including the expansion<P>
of type specifiers which are nested within the expansion.<P>
<P>
Clarify that the consequences are undefined if the result of<P>
fully expanding a type specifier contains any circular <A REL=DEFINITION HREF="../Body/f_docume.htm#structure"><B>structure</B></A>,<P>
except within the objects referred to by <A REL=DEFINITION HREF="../Body/a_member.htm#member"><B>MEMBER</B></A> and <A REL=DEFINITION HREF="../Body/a_eql.htm#eql"><B>EQL</B></A> type<P>
specifiers.<P>
<P>
Clarify that recursive expansion of the form returned as the<P>
expansion of a <A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> must terminate, including the expansion <P>
of other macros which are subforms of other forms returned by<P>
<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A>.<P>
<P>
Clarify that the consequences are undefined if the result of fully<P>
macroexpanding a form contains any non-constant circular list<P>
<A REL=DEFINITION HREF="../Body/f_docume.htm#structure"><B>structure</B></A>.<P>
<P>
<B>Rationale:<P>
</B><P>
This probably protects the status quo in most implementations,<P>
while giving users a clear sense of what's reasonable and what's not.<P>
<P>
<B>Test Cases:<P>
</B><P>
These test cases are more contrived in nature, but are chosen to be <P>
actually plausible to test in existing implementations (something not<P>
true of the cases mentioned in the problem description):<P>
<P>
#1: (<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> RETURNS-T (X) X)<P>
(<A REL=DEFINITION HREF="../Body/m_deftp.htm#deftype"><B>DEFTYPE</B></A> FOO () '(<A REL=DEFINITION HREF="../Body/a_or.htm#or"><B>OR</B></A> (<A REL=DEFINITION HREF="../Body/t_satisf.htm#satisfies"><B>SATISFIES</B></A> RETURNS-T) FOO))<P>
<P>
This is an error because in (<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> X 'FOO), FOO cannot, in general,<P>
be fully expanded because the expansion does not terminate.<P>
<P>
#2: (<A REL=DEFINITION HREF="../Body/m_deftp.htm#deftype"><B>DEFTYPE</B></A> FOO (<A REL=DEFINITION HREF="../Body/03_da.htm#AMkey"><B>&amp;KEY</B></A> (FAST <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>))<P>
(<A REL=DEFINITION HREF="../Body/s_if.htm#if"><B>IF</B></A> FAST <P>
`(<A REL=DEFINITION HREF="../Body/t_satisf.htm#satisfies"><B>SATISFIES</B></A> FOO-FAST)<P>
`(<A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>AND</B></A> <A REL=DEFINITION HREF="../Body/t_symbol.htm#symbol"><B>SYMBOL</B></A> (FOO :FAST T))))<P>
<P>
This is well-defined because in (<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> X 'FOO), FOO can, in general,<P>
be fully expanded without error because the recursion always terminates.<P>
<P>
#3: Macro definitions like:<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> MAPCAR1 (FN <A REL=DEFINITION HREF="../Body/a_list.htm#list"><B>LIST</B></A>)<P>
`(<A REL=DEFINITION HREF="../Body/s_if.htm#if"><B>IF</B></A> (<A REL=DEFINITION HREF="../Body/a_null.htm#null"><B>NULL</B></A> ,<A REL=DEFINITION HREF="../Body/a_list.htm#list"><B>LIST</B></A>) '()<P>
(<A REL=DEFINITION HREF="../Body/a_cons.htm#cons"><B>CONS</B></A> (<A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>FUNCALL</B></A> ,FN (<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>CAR</B></A> ,<A REL=DEFINITION HREF="../Body/a_list.htm#list"><B>LIST</B></A>))<P>
(MAPCAR1 ,FN (<A REL=DEFINITION HREF="../Body/f_car_c.htm#cdr"><B>CDR</B></A> ,<A REL=DEFINITION HREF="../Body/a_list.htm#list"><B>LIST</B></A>)))))<P>
<P>
would be explicitly undefined.<P>
<P>
#4: Forms involving explicit circularities, such as<P>
<P>
(<A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>PROGN</B></A> . #1=((<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO) . #1#))<P>
<P>
would be explicitly undefined.<P>
<P>
#5: Type specifiers involving explicit circularities, such as<P>
<P>
a. (<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> 3 '(<A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>AND</B></A> #1=(T . #1#)))<P>
<P>
would be explicitly undefined, except for cases like<P>
<P>
b. (<A REL=DEFINITION HREF="../Body/f_typep.htm#typep"><B>TYPEP</B></A> 3 '(<A REL=DEFINITION HREF="../Body/a_eql.htm#eql"><B>EQL</B></A> #1=(T . #1#)))<P>
<P>
which would still be well-defined.<P>
<P>
<B>Current Practice:<P>
</B><P>
Genera implements this proposal.<P>
<P>
#1: The proposal makes this an error.<P>
Genera uses a TYPE-EXPAND function internally at compile time and<P>
so cannot handle this case.<P>
<P>
#2: The proposal requires this to work.<P>
Genera handles this case.<P>
<P>
#3: The proposal makes this an error.<P>
Genera can manage to do (<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 3)) as a standalone form,<P>
but blows out during lexical analysis both in the interpreter and<P>
compiler if you put it in a definition.<P>
<P>
#4: The proposal makes this case an error.<P>
Genera can't handle this case at all.<P>
<P>
#5: The proposal makes #5a an error but requires #5b to work.<P>
Genera doesn't handle #5a but does handle #5b.<P>
<P>
<B>Cost to Implementors:<P>
</B><P>
Probably none.<P>
<P>
<B>Cost to Users:<P>
</B><P>
Little or none. Code which exploited the erroneous cases were already<P>
not portable in practice, so probably no users relied on them.<P>
<P>
<B>Cost of Non-Adoption:<P>
</B><P>
Portability pitfalls waiting for unsuspecting users.<P>
<P>
<B>Benefits:<P>
</B><P>
Compiler writers who didn't want to handle this won't go to sleep every<P>
night in fear that they really should have and that some day someone will<P>
be knocking on their door asking why not.<P>
<P>
<B>Aesthetics:<P>
</B><P>
This is intended to be equivalent to the status quo for macros, although<P>
it doesn't have to be spelled out there because the presence of <A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand"><B>MACROEXPAND</B></A><P>
pretty much forces it. In any case, it clarifies that <A REL=DEFINITION HREF="../Body/m_deftp.htm#deftype"><B>DEFTYPE</B></A> and <A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A><P>
must be essentially consistent on this issue.<P>
<P>
<B>Discussion:<P>
</B><P>
Pitman supports this proposal.<P>
<P>
If Sandra Loosemore's TYPE-EXPAND proposal (part of issue TYPE-SPECIFIER-P)<P>
passed, this view of the world would pretty much be forced anyway.<P>
<P>
Of Margolin's example, Rob MacLachlan (at CMU) wrote:<P>
``I am fairly sure that nobody has addressed this issue. <P>
Although I have been aware of it, I kept quiet about it, <P>
because my compiler gags on recursive deftypes, and I was<P>
afraid someone would decide that was a bug.''<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>