651 lines
47 KiB
HTML
651 lines
47 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 DOTIMES-IGNORE 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/iss136_w.htm">
|
||
|
<LINK REL=UP HREF="../Issues/iss137.htm">
|
||
|
<LINK REL=NEXT HREF="../Issues/iss138_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/iss136_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="../Issues/iss137.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="../Issues/iss138_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
|
||
|
|
||
|
<HR>
|
||
|
|
||
|
|
||
|
|
||
|
<H2>Issue DOTIMES-IGNORE Writeup</H2>
|
||
|
|
||
|
<PRE><B>Issue:</B> <A HREF="iss137.htm">DOTIMES-IGNORE</A><P>
|
||
|
<B>Forum:</B> Cleanup<P>
|
||
|
<B>References:</B> <A REL=DEFINITION HREF="../Body/m_dolist.htm#dolist"><B>DOLIST</B></A> (p126), <A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (p126-128), <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> (p160), <P>
|
||
|
<A REL=DEFINITION HREF="../Body/m_loop.htm#loop"><B>LOOP</B></A> (X3J13/89-004), <A REL=DEFINITION HREF="../Body/m_do_sym.htm#do-symbols"><B>DO-SYMBOLS</B></A> (p187), <A REL=DEFINITION HREF="../Body/m_do_sym.htm#do-all-symbols"><B>DO-ALL-SYMBOLS</B></A> (p188),<P>
|
||
|
<A REL=DEFINITION HREF="../Body/m_do_sym.htm#do-external-symbols"><B>DO-EXTERNAL-SYMBOLS</B></A> (p187), <A REL=DEFINITION HREF="../Body/m_do_do.htm#do"><B>DO</B></A> (pp122-126), <A REL=DEFINITION HREF="../Body/m_do_do.htm#doST"><B>DO*</B></A> (pp122-126)<P>
|
||
|
<B>Category:</B> CLARIFICATION<P>
|
||
|
<B>Edit history:</B> 20-Jul-90, Version 1 by Pitman<P>
|
||
|
06-Mar-91, Version 2 by Pitman<P>
|
||
|
15-Mar-91, Version 3 by Pitman<P>
|
||
|
<B>Status:</B> For Internal Discussion<P>
|
||
|
<P>
|
||
|
<B>Problem Description:<P>
|
||
|
</B><P>
|
||
|
The <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> declaration is described in terms of whether a variable is<P>
|
||
|
`used'. But what constitutes a use? Several iteration primitives are<P>
|
||
|
described as macros, and the nature of the expansion is not well<P>
|
||
|
enough specified for the answer to this question to be easily<P>
|
||
|
determined.<P>
|
||
|
<P>
|
||
|
Consider:<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (A 3) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))<P>
|
||
|
Is A used? Would it be appropriate to write:<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (A 3) (<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> A)) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))<P>
|
||
|
In some implementations, this would seem to be desirable, while in<P>
|
||
|
other implementations it would seem undesirable.<P>
|
||
|
<P>
|
||
|
In some implementations, such as an older Genera release, when the <P>
|
||
|
compiler sees an <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> declaration, it `commits' the fact that the<P>
|
||
|
variable will not be used and sometimes cannot later back out and<P>
|
||
|
produce a successful compilation when this assumption is later realized<P>
|
||
|
to be wrong in the process of code-walking. Because such a program<P>
|
||
|
is technically in error, this is a conforming situation. But it<P>
|
||
|
means that the choice of whether to use <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> or not has potential<P>
|
||
|
semantic impact.<P>
|
||
|
<P>
|
||
|
This issue started out as being just about <A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (hence the name)<P>
|
||
|
but has been generalized to include all CL iteration forms.<P>
|
||
|
<P>
|
||
|
<B>Terminology:<P>
|
||
|
</B><P>
|
||
|
For the purposes of this issue, the following terminology applies:<P>
|
||
|
<P>
|
||
|
An "explicit use of a variable in a form" is a use that would be<P>
|
||
|
apparent in the normal semantics of the form. That is, if all<P>
|
||
|
subforms of that form were macroexpanded, but the form itself were<P>
|
||
|
not. [This isn't how an implementation has to detect an explicit <P>
|
||
|
form; it's just a definition of what explicit use means. The intent<P>
|
||
|
is that an explicit use be one which does not expose any undocumented<P>
|
||
|
details of the form's macro expansion (if the form is in fact a macro).]<P>
|
||
|
<P>
|
||
|
An "iteration form" means a <A REL=DEFINITION HREF="../Body/m_dolist.htm#dolist"><B>DOLIST</B></A>, <A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A>, <A REL=DEFINITION HREF="../Body/m_loop.htm#loop"><B>LOOP</B></A>, <A REL=DEFINITION HREF="../Body/m_do_sym.htm#do-symbols"><B>DO-SYMBOLS</B></A>, <P>
|
||
|
<A REL=DEFINITION HREF="../Body/m_do_sym.htm#do-all-symbols"><B>DO-ALL-SYMBOLS</B></A>, <A REL=DEFINITION HREF="../Body/m_do_sym.htm#do-external-symbols"><B>DO-EXTERNAL-SYMBOLS</B></A>, <A REL=DEFINITION HREF="../Body/m_do_do.htm#do"><B>DO</B></A>, or <A REL=DEFINITION HREF="../Body/m_do_do.htm#doST"><B>DO*</B></A> form.<P>
|
||
|
<P>
|
||
|
An "iteration variable" is a variable which is "explicitly used"<P>
|
||
|
as a variable to be bound by by an "iteration form".<P>
|
||
|
<P>
|
||
|
Voting Instructions:<P>
|
||
|
<P>
|
||
|
Proposals which have a "+" in their name are compatible with any<P>
|
||
|
other proposals, and may be voted in addition to the other proposals.<P>
|
||
|
<P>
|
||
|
<B>Proposal (DOTIMES-IGNORE:NEVER):<P>
|
||
|
</B><P>
|
||
|
Clarify that iteration variables are, by definition, always `used'. <P>
|
||
|
That is, clarify that using<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> ...))<P>
|
||
|
for such an iteration variable has undefined consequences.<P>
|
||
|
<P>
|
||
|
Rationale:<P>
|
||
|
<P>
|
||
|
This is analagous to the situation in <A REL=DEFINITION HREF="../Body/m_defmet.htm#defmethod"><B>DEFMETHOD</B></A> where a specialized <P>
|
||
|
required argument is considered a use of the argument.<P>
|
||
|
<P>
|
||
|
Example:<P>
|
||
|
<P>
|
||
|
;; The following would be correct and should not be warned about.<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I 5)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))<P>
|
||
|
<P>
|
||
|
;; The following would not be correct and might be warned about.<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I 5)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> I))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))<P>
|
||
|
<P>
|
||
|
<B>Proposal (DOTIMES-IGNORE:UNLESS-EXPLICIT):<P>
|
||
|
</B><P>
|
||
|
Clarify that unless an variable in an iteration form is explicitly <P>
|
||
|
used in the form which binds it, it might be considered "unused" by<P>
|
||
|
the implementation, and that it is always permissible to use<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> ...))<P>
|
||
|
for such a unused variable.<P>
|
||
|
<P>
|
||
|
Rationale:<P>
|
||
|
<P>
|
||
|
This doesn't force users to think about the macro expansion and tends<P>
|
||
|
to treat iteration variables more like variables bound by <A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A>, <A REL=DEFINITION HREF="../Body/s_let_l.htm#letST"><B>LET*</B></A>,<P>
|
||
|
and <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A>.<P>
|
||
|
<P>
|
||
|
Example:<P>
|
||
|
<P>
|
||
|
;; The following would be correct and should not be warned about.<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I 5)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> I))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))<P>
|
||
|
<P>
|
||
|
;; The following would not be correct and might be warned about.<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I 5)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))<P>
|
||
|
<P>
|
||
|
<B>Proposal (DOTIMES-IGNORE:INVISIBLE-REFERENCES):<P>
|
||
|
</B><P>
|
||
|
Introduce a macro<P>
|
||
|
<P>
|
||
|
WITH-INVISIBLE-REFERENCES ({vars}*) {forms}* [Macro]<P>
|
||
|
<P>
|
||
|
Within the context of this macro, any uses of the <vars> are not<P>
|
||
|
regarded as `uses' of the <vars> for the purposes of compiler warnings.<P>
|
||
|
<P>
|
||
|
Clarify that macros like <A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> which expand into code which do<P>
|
||
|
invisible computations on user-supplied variables must do the equivalent<P>
|
||
|
of wrapping WITH-INVISIBLE-REFERNCES around those invisible uses, so that<P>
|
||
|
those uses will not be counted as uses.<P>
|
||
|
<P>
|
||
|
Rationale:<P>
|
||
|
<P>
|
||
|
This makes the mechanism for invisible uses available to users so that they<P>
|
||
|
can write forms like <A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> which manipulate user-supplied variables <P>
|
||
|
and yet warn about lack of explicit use of those variables.<P>
|
||
|
<P>
|
||
|
Example:<P>
|
||
|
<P>
|
||
|
;; The following would be correct and should not be warned about.<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I 5)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> I))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))<P>
|
||
|
<P>
|
||
|
;; The following would not be correct and might be warned about.<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I 5)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))<P>
|
||
|
<P>
|
||
|
;; The following would be correct. User might be warned that X <P>
|
||
|
;; is not used. (This is a pathological case which wouldn't be a<P>
|
||
|
;; normal use. For a `real' use see the expansion of <A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> in<P>
|
||
|
;; the Symbolics Genera current practice.)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((X 3))<P>
|
||
|
(WITH-INVISIBLE-REFERENCES (X) (<A REL=DEFINITION HREF="../Body/m_incf_.htm#incf"><B>INCF</B></A> X) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> X))<P>
|
||
|
0)<P>
|
||
|
4<P>
|
||
|
=> 0<P>
|
||
|
<P>
|
||
|
<B>Proposal (DOTIMES-IGNORE:+IGNORE-FUNCTION):<P>
|
||
|
</B><P>
|
||
|
Introduce a function <P>
|
||
|
<P>
|
||
|
<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> <A REL=DEFINITION HREF="../Body/03_da.htm#AMrest"><B>&REST</B></A> <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> [Function]<P>
|
||
|
<P>
|
||
|
Accepts any number of arguments and returns <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>.<P>
|
||
|
<P>
|
||
|
Function calls to <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> can effectively be optimized away by a compiler,<P>
|
||
|
except where side-effects might occur. That is, (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> X #'Y (Z)) is<P>
|
||
|
equivalent to (<A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>PROGN</B></A> X #'Y (Z) <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>), but is more perspicuous about the<P>
|
||
|
user's intent to identify ignored items.<P>
|
||
|
<P>
|
||
|
Rationale:<P>
|
||
|
<P>
|
||
|
This leaves the original problem in place but provides a compromise <P>
|
||
|
that people can learn to use. It also has the side benefit of providing<P>
|
||
|
an obvious syntax for `<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignorable"><B>ignorable</B></A>' variables introduced by some macros.<P>
|
||
|
It also provides an obvious syntax for ignoring <A REL=DEFINITION HREF="../Body/s_flet_.htm#flet"><B>FLET</B></A>'d items. <P>
|
||
|
<P>
|
||
|
Example:<P>
|
||
|
<P>
|
||
|
;; The following might or might not be correct and might be warned about.<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I 5)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> I))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))<P>
|
||
|
<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I 5)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))<P>
|
||
|
<P>
|
||
|
;; The following would not be warned about.<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I 5)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> I)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))<P>
|
||
|
<P>
|
||
|
<B>Proposal (DOTIMES-IGNORE:+STYLE-WARNING):<P>
|
||
|
</B><P>
|
||
|
Clarify that any `unused variable' warning must be a <A REL=DEFINITION HREF="../Body/e_style_.htm#style-warning"><B>STYLE-WARNING</B></A>, and<P>
|
||
|
may not affect program semantics.<P>
|
||
|
<P>
|
||
|
Rationale:<P>
|
||
|
<P>
|
||
|
This is similar to STATUS-QUO, but at least insures that the issue has<P>
|
||
|
no semantic impact on code.<P>
|
||
|
<P>
|
||
|
Example:<P>
|
||
|
<P>
|
||
|
;; The following might or might not be correct and might be warned about<P>
|
||
|
;; but could be suppressed in a context where style warnings were <P>
|
||
|
;; suppressable. In either case, correct code would be generated.<P>
|
||
|
<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I 5)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> I))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))<P>
|
||
|
<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I 5)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))<P>
|
||
|
<P>
|
||
|
<B>Proposal (DOTIMES-IGNORE:+NEW-DECLARATION):<P>
|
||
|
</B><P>
|
||
|
Introduce a new declaration, <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignorable"><B>IGNORABLE</B></A>, similar to <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A>, except that<P>
|
||
|
it means that the variable might or might not be used, but that in <P>
|
||
|
neither case should a warning be issued.<P>
|
||
|
<P>
|
||
|
Rationale:<P>
|
||
|
<P>
|
||
|
A lot of people have asked for this. e.g., it would be useful for <P>
|
||
|
places where variables pop out of nowhere due to the presence of some<P>
|
||
|
macro. e.g., in New Flavors (think of it as a user program from the<P>
|
||
|
point of view of this proposal) the variable SELF magically appears in a<P>
|
||
|
<A REL=DEFINITION HREF="../Body/m_defmet.htm#defmethod"><B>DEFMETHOD</B></A>. The definition of FLAVOR:DEFMETHOD might, therefore, want<P>
|
||
|
to declare SELF to be <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignorable"><B>IGNORABLE</B></A> since not all Flavors' <A REL=DEFINITION HREF="../Body/m_defmet.htm#defmethod"><B>DEFMETHOD</B></A> forms<P>
|
||
|
actually use this.<P>
|
||
|
<P>
|
||
|
Example:<P>
|
||
|
<P>
|
||
|
Given...<P>
|
||
|
<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> WITH-FOO (X <A REL=DEFINITION HREF="../Body/03_dd.htm#AMbody"><B>&BODY</B></A> STUFF)<P>
|
||
|
`(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((FOO (FROB ,X)))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignorable"><B>IGNORABLE</B></A> FOO))<P>
|
||
|
,@STUFF))<P>
|
||
|
<P>
|
||
|
Neither of the following two uses would be warned about:<P>
|
||
|
<P>
|
||
|
(WITH-FOO (F) (G))<P>
|
||
|
or (WITH-FOO (F) (H FOO))<P>
|
||
|
<P>
|
||
|
<B>Proposal (DOTIMES-IGNORE:+FUNCTION-DECLARATIONS):<P>
|
||
|
</B><P>
|
||
|
Permit the <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> (and <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignorable"><B>IGNORABLE</B></A>, if it passes--see proposal<P>
|
||
|
+NEW-DECLARATION) declarations to contain references to #'name <P>
|
||
|
in order to refer to a function name instead of a variable name.<P>
|
||
|
<P>
|
||
|
Rationale:<P>
|
||
|
<P>
|
||
|
This would be useful, for example, in the expansion of <A REL=DEFINITION HREF="../Body/m_defmet.htm#defmethod"><B>DEFMETHOD</B></A><P>
|
||
|
in order to declare that <A REL=DEFINITION HREF="../Body/f_call_n.htm#call-next-method"><B>CALL-NEXT-METHOD</B></A> and <A REL=DEFINITION HREF="../Body/f_next_m.htm#next-method-p"><B>NEXT-METHOD-P</B></A> might<P>
|
||
|
or might not be used, but that no warning should be produced in<P>
|
||
|
either case. Some user programs presumably have similar needs.<P>
|
||
|
<P>
|
||
|
Example:<P>
|
||
|
<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> <A REL=DEFINITION HREF="../Body/m_defmet.htm#defmethod"><B>DEFMETHOD</B></A> ...<P>
|
||
|
`(... (<A REL=DEFINITION HREF="../Body/s_flet_.htm#flet"><B>FLET</B></A> ((<A REL=DEFINITION HREF="../Body/f_call_n.htm#call-next-method"><B>CALL-NEXT-METHOD</B></A> ...)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_next_m.htm#next-method-p"><B>NEXT-METHOD-P</B></A> ...))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignorable"><B>IGNORABLE</B></A> #'<A REL=DEFINITION HREF="../Body/f_call_n.htm#call-next-method"><B>CALL-NEXT-METHOD</B></A><P>
|
||
|
#'<A REL=DEFINITION HREF="../Body/f_next_m.htm#next-method-p"><B>NEXT-METHOD-P</B></A>))<P>
|
||
|
...)))<P>
|
||
|
<P>
|
||
|
<B>Proposal (DOTIMES-IGNORE:STATUS-QUO):<P>
|
||
|
</B><P>
|
||
|
Accept the fact that the use of (<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> ...)) for an iteration<P>
|
||
|
variable will always cause a warning in some implementations and that<P>
|
||
|
the failure to use it will always cause a warning in some other <P>
|
||
|
implementations. The net effect of this will be that no code which uses <P>
|
||
|
any iteration primitive, <A REL=DEFINITION HREF="../Body/m_do_do.htm#do"><B>DO</B></A>, <A REL=DEFINITION HREF="../Body/m_loop.htm#loop"><B>LOOP</B></A>, or otherwise without using all iteration<P>
|
||
|
variables explicitly will be free from gratuitous whining of at least<P>
|
||
|
some compilers. Since the presence of <P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> ...))<P>
|
||
|
is sometimes fatal to some compilers, people will learn to live without it,<P>
|
||
|
or will introduce creative other ways to `use' the variable to muffle the<P>
|
||
|
warnings, sometimes at a performance penalty.<P>
|
||
|
<P>
|
||
|
Rationale:<P>
|
||
|
<P>
|
||
|
Implements the status quo.<P>
|
||
|
<P>
|
||
|
Example:<P>
|
||
|
<P>
|
||
|
;; The following might or might not be correct and might be warned about.<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I 5)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> I))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))<P>
|
||
|
<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I 5)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))<P>
|
||
|
<P>
|
||
|
<B>Test Case:<P>
|
||
|
</B><P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> COMPILER-WARNINGS-P (BODIES <A REL=DEFINITION HREF="../Body/03_da.htm#AMoptional"><B>&OPTIONAL</B></A> (FLAG <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_mapc_.htm#mapcar"><B>MAPCAR</B></A> #'(<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> (BODY)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_flet_.htm#flet"><B>FLET</B></A> ((TRY (BODY)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((<A REL=DEFINITION HREF="../Body/e_warnin.htm#warning"><B>WARNING</B></A> <P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_w_out_.htm#with-output-to-string"><B>WITH-OUTPUT-TO-STRING</B></A> (<A REL=DEFINITION HREF="../Body/v_debug_.htm#STerror-outputST"><B>*ERROR-OUTPUT*</B></A>)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A> <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> `(<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> ,@BODY)))))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_if.htm#if"><B>IF</B></A> FLAG <A REL=DEFINITION HREF="../Body/e_warnin.htm#warning"><B>WARNING</B></A> (> (<A REL=DEFINITION HREF="../Body/f_length.htm#length"><B>LENGTH</B></A> <A REL=DEFINITION HREF="../Body/e_warnin.htm#warning"><B>WARNING</B></A>) 0)))))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/a_list.htm#list"><B>LIST</B></A> (TRY BODY)<P>
|
||
|
(TRY (<A REL=DEFINITION HREF="../Body/a_list.htm#list"><B>LIST</B></A> (<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>CAR</B></A> BODY)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_rm_rm.htm#remove-if"><B>REMOVE-IF</B></A><P>
|
||
|
#'(<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> (X)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>AND</B></A> (<A REL=DEFINITION HREF="../Body/a_not.htm#not"><B>NOT</B></A> (<A REL=DEFINITION HREF="../Body/a_atom.htm#atom"><B>ATOM</B></A> X))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_eq.htm#eq"><B>EQ</B></A> (<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>CAR</B></A> X) '<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A>)))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_car_c.htm#cadr"><B>CADR</B></A> BODY)))))))<P>
|
||
|
BODIES))<P>
|
||
|
<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> TEST-CASE ()<P>
|
||
|
(COMPILER-WARNINGS-P<P>
|
||
|
'(((X) (<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (A X) (<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> A)) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO)))<P>
|
||
|
((X) (<A REL=DEFINITION HREF="../Body/m_dolist.htm#dolist"><B>DOLIST</B></A> (A X) (<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> A)) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO)))<P>
|
||
|
((X) (<A REL=DEFINITION HREF="../Body/m_do_sym.htm#do-symbols"><B>DO-SYMBOLS</B></A> (S X) (<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> S)) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO)))<P>
|
||
|
((X) (<A REL=DEFINITION HREF="../Body/m_do_sym.htm#do-external-symbols"><B>DO-EXTERNAL-SYMBOLS</B></A> (S X) (<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> S)) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO)))<P>
|
||
|
(() (<A REL=DEFINITION HREF="../Body/m_do_sym.htm#do-all-symbols"><B>DO-ALL-SYMBOLS</B></A> (S) (<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> S)) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO)))<P>
|
||
|
((X) (<A REL=DEFINITION HREF="../Body/m_loop.htm#loop"><B>LOOP</B></A> FOR I IN X <A REL=DEFINITION HREF="../Body/m_do_do.htm#do"><B>DO</B></A> (<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> I)) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO)))<P>
|
||
|
((X) (<A REL=DEFINITION HREF="../Body/m_loop.htm#loop"><B>LOOP</B></A> FOR L ON X <A REL=DEFINITION HREF="../Body/m_do_do.htm#do"><B>DO</B></A> (<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> L)) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO)))<P>
|
||
|
((X) (<A REL=DEFINITION HREF="../Body/m_do_do.htm#do"><B>DO</B></A> ((L X X)) (<A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>) (<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> L)) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO)))<P>
|
||
|
((X) (<A REL=DEFINITION HREF="../Body/m_do_do.htm#doST"><B>DO*</B></A> ((L X X)) (<A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>) (<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> L)) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO))))))<P>
|
||
|
<P>
|
||
|
<B>Current Practice:<P>
|
||
|
</B><P>
|
||
|
Symbolics Genera implements INVISIBLE-REFERENCES (except that the<P>
|
||
|
macro is called COMPILER:INVISIBLE-REFERENCES) and by implication<P>
|
||
|
it implements UNLESS-EXPLICIT and STATUS-QUO. It also implements <P>
|
||
|
+IGNORE-FUNCTION, and probably implements +STYLE-WARNING.<P>
|
||
|
<P>
|
||
|
Test case results...<P>
|
||
|
Symbolics Genera 8.0.1: ((<A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> T) (T T ) (T <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>) (T <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>) (T <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>)<P>
|
||
|
(T T) (T T ) (T T ) (T T ))<P>
|
||
|
<P>
|
||
|
Symbolics Genera 8.1: ((<A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> T) (<A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> T) (T <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>) (T <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>) (T <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>)<P>
|
||
|
(T T) (T T) (T T ) (T T ))<P>
|
||
|
<P>
|
||
|
Symbolics Cloe: ((<A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> T) (T T ) (<A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>) (T <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>) (T T )<P>
|
||
|
(T T) (T <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>) (T T ) (T T ))<P>
|
||
|
<P>
|
||
|
In Symbolics Genera, the macroexpansion of (<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (A 3) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO)) is:<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_prog_.htm#prog"><B>PROG</B></A> ((A 0))<P>
|
||
|
#:G1689 (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO)<P>
|
||
|
(COMPILER:INVISIBLE-REFERENCES (A)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_if.htm#if"><B>IF</B></A> (<A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>PROGN</B></A> (<A REL=DEFINITION HREF="../Body/s_setq.htm#setq"><B>SETQ</B></A> A (<A REL=DEFINITION HREF="../Body/f_1pl_1_.htm#1PL"><B>1+</B></A> A))<P>
|
||
|
(< A 3))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>PROGN</B></A> (<A REL=DEFINITION HREF="../Body/s_go.htm#go"><B>GO</B></A> #:G1689))))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_return.htm#return"><B>RETURN</B></A> <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>))<P>
|
||
|
<P>
|
||
|
<B>Cost to Implementors:<P>
|
||
|
</B><P>
|
||
|
NEVER: Relatively small. It's straightforward for macros to add a few<P>
|
||
|
spurious additional references in order to assure that no unused warnings<P>
|
||
|
occur.<P>
|
||
|
<P>
|
||
|
UNLESS-EXPLICIT: Medium. This is similar to INVISIBLE-REFERENCES, but<P>
|
||
|
it allows for alternate implementations with equivalent effect because<P>
|
||
|
it doesn't publish the interface.<P>
|
||
|
<P>
|
||
|
+IGNORE-FUNCTION: Relatively small.<P>
|
||
|
<P>
|
||
|
+NEW-DECLARATION: None to medium. This involves some compiler work,<P>
|
||
|
the amount of which may vary, for implementations that do enough<P>
|
||
|
bookkeeping for it to matter. Implementations which don't ever warn<P>
|
||
|
can just ignore this, of course.<P>
|
||
|
<P>
|
||
|
+FUNCTION-DECLARATIONS: Probably relatively small.<P>
|
||
|
<P>
|
||
|
INVISIBLE-REFERENCES: None to Medium. This probably involves some<P>
|
||
|
compiler hacking for implementations who care to do this kind of <P>
|
||
|
warning. Strictly, an implementation could simply never warn, and then<P>
|
||
|
this would be free, but some implementations have already established<P>
|
||
|
a precedent of warning, so their customers would probably insist that<P>
|
||
|
they did the work to make warnings continue to work in places where<P>
|
||
|
they were called for.<P>
|
||
|
<P>
|
||
|
STATUS-QUO: None.<P>
|
||
|
<P>
|
||
|
<B>Cost to Users:<P>
|
||
|
</B><P>
|
||
|
NEVER: Relatively small.<P>
|
||
|
<P>
|
||
|
UNLESS-EXPLICIT: Relatively small.<P>
|
||
|
<P>
|
||
|
+IGNORE-FUNCTION: Relatively small.<P>
|
||
|
<P>
|
||
|
+NEW-DECLARATION: None.<P>
|
||
|
<P>
|
||
|
+FUNCTION-DECLARATIONS: None.<P>
|
||
|
<P>
|
||
|
INVISIBLE-REFERENCES: Relatively small.<P>
|
||
|
<P>
|
||
|
STATUS-QUO: Potentially large nuisance value and medium amount of work<P>
|
||
|
for some users.<P>
|
||
|
When porting to a new platform, you get a lot of warnings. Sometimes<P>
|
||
|
the warnings are useful, sometimes they are not. The worst part is<P>
|
||
|
if they are not useful and you just want to ignore them but you can't<P>
|
||
|
because there are other warnings you want to see and you don't have the<P>
|
||
|
ability to turn off just these warnings. So over and over you have to<P>
|
||
|
wade through these warnings just to get to the others.<P>
|
||
|
<P>
|
||
|
<B>Cost of Non-Adoption:<P>
|
||
|
</B><P>
|
||
|
See cost of option STATUS-QUO.<P>
|
||
|
<P>
|
||
|
<B>Benefits:<P>
|
||
|
</B><P>
|
||
|
Users don't have to guess about important aspects of language semantics.<P>
|
||
|
<P>
|
||
|
<B>Aesthetics:<P>
|
||
|
</B><P>
|
||
|
Proposals NEVER, UNLESS-EXPLICIT, +IGNORE-FUNCTION, +NEW-DECLARATION,<P>
|
||
|
+FUNCTION-DECLARATIONS, and INVISIBLE-REFERENCES definitely improve the<P>
|
||
|
aesthetics in the sense that they give the user the power to make the<P>
|
||
|
code mean a particular thing, rather than leaving it to the discretion<P>
|
||
|
of the implementation what the user meant.<P>
|
||
|
<P>
|
||
|
Proposal STATUS-QUO is not aesthetic.<P>
|
||
|
<P>
|
||
|
<B>Discussion:<P>
|
||
|
</B><P>
|
||
|
Pitman thinks that anything but STATUS-QUO is livable, but has a<P>
|
||
|
preference for either INVISIBLE-REFERENCES or NEVER. He thinks <P>
|
||
|
any of +IGNORE-FUNCTION, +NEW-DECLARATION, and +FUNCTION-DECLARATIONS<P>
|
||
|
would be nice additions, too.<P>
|
||
|
<P>
|
||
|
Dalton is on record as opposing a WITH-INVISIBLE-REFERENCES macro<P>
|
||
|
and an <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignorable"><B>IGNORABLE</B></A> declaration (see below), but he hasn't seen this<P>
|
||
|
specific proposal (which admittedly isn't likely to change his mind).<P>
|
||
|
<P>
|
||
|
Several Symbolics customers have complained about portability<P>
|
||
|
problems due to this lack of specificity.<P>
|
||
|
<P>
|
||
|
Gregor Kiczales says: ``in writing PCL, this <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> issue was a <P>
|
||
|
major pain in the ass. I never really was able to get it right,<P>
|
||
|
and it ended up showing through to the users.''<P>
|
||
|
<P>
|
||
|
JonL White said of mail from Dalton in a much longer discussion:<P>
|
||
|
``he claims that DECLARE-IGNORE is *not* just friendly, <P>
|
||
|
optional advice to the compiler, but assertions about<P>
|
||
|
the program. I may disagree with him, but I can certainly<P>
|
||
|
sympathesize with his viewpoint. This issue in general<P>
|
||
|
-- what *must* declarations do -- is a serious one.''<P>
|
||
|
<P>
|
||
|
Margolin said ``We're past the deadline for making significant changes<P>
|
||
|
in the language. We're trying to get the <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A> edited now. At this<P>
|
||
|
time we shouldn't be making changes unless they fix real language<P>
|
||
|
bugs. I personally don't feel that a style warning is sufficient<P>
|
||
|
justification for a change to the semantics of <A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A>.'' RWK<P>
|
||
|
responded ``I feel that the style warnings *ARE* an important enough<P>
|
||
|
issue, because these style warnings are by default dictating the<P>
|
||
|
variable semantics, but in a manner inconsistent from implementation<P>
|
||
|
to implementation.''<P>
|
||
|
<P>
|
||
|
Some people reviewing version 1 made suggestions which are not<P>
|
||
|
pursued in this version, but which are worthy of note:<P>
|
||
|
<P>
|
||
|
- GLS suggested we might need a REPEAT macro, such that <P>
|
||
|
(REPEAT n . body) meant the same as (<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I n) . body).<P>
|
||
|
This would paper over the <A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> problem, but would still <P>
|
||
|
leave other similar problems unattended to. This angle was<P>
|
||
|
therefore not pursued.<P>
|
||
|
<P>
|
||
|
- Barrett and others raised the issue of what counts as a use.<P>
|
||
|
Both reading and writing it, or just reading? Technically,<P>
|
||
|
that's an orthogonal issue, although it has obvious interplay <P>
|
||
|
with anything decided here.<P>
|
||
|
<P>
|
||
|
- There was discussion by Dalton, Margolin, and others of changing<P>
|
||
|
the semantics of <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> to mean `<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignorable"><B>ignorable</B></A>'. Some felt this <P>
|
||
|
would be visually confusing. Some felt we should rename <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A><P>
|
||
|
to <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignorable"><B>IGNORABLE</B></A>. Some felt we should introduce <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignorable"><B>IGNORABLE</B></A> in <P>
|
||
|
addition to <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A>. [An <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignorable"><B>IGNORABLE</B></A> declaration was added as an<P>
|
||
|
option in v3 of this proposal. -kmp]<P>
|
||
|
<P>
|
||
|
- Jeff Barnett (at Northrop) suggested that we should reconsider<P>
|
||
|
the idea of dignifying a certain variable, <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A>, as implicitly<P>
|
||
|
ignored and then permit (<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> 5) ...). He observed<P>
|
||
|
that this also works for (<A REL=DEFINITION HREF="../Body/m_multip.htm#multiple-value-bind"><B>MULTIPLE-VALUE-BIND</B></A> (X <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> Z) ...).<P>
|
||
|
This was already brought up as issue IGNORE-VARIABLE (tabled by<P>
|
||
|
Masinter at Mar-89 meeting due to deadline constraints).<P>
|
||
|
Fred White (at BBN) suggested that it should be possible to do<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_procla.htm#proclaim"><B>PROCLAIM</B></A> '(<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A>)). Pitman pointed out that <P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_procla.htm#proclaim"><B>PROCLAIM</B></A> '(<A REL=DEFINITION HREF="../Body/d_specia.htm#special"><B>SPECIAL</B></A> <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A>)) almost works.<P>
|
||
|
Neil Goldman (at ISI) raised the issue of <P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_mapc_.htm#mapcar"><B>mapcar</B></A> #'(<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> (V) t) l)<P>
|
||
|
which again calls for the <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> variable.<P>
|
||
|
<P>
|
||
|
- Eliot@CS.UMASS.EDU pointed out that he just tries to avoid <P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> X)) in favor of just X at toplevel of a body.<P>
|
||
|
Don Cohen (at ISI) disagreed that this was adequate, saying that<P>
|
||
|
he felt that an implementor would be justified in finding such<P>
|
||
|
a `use' to be gratuitous and still warning. (Pitman disagrees<P>
|
||
|
with this disagreement, because sometimes macros expand into <P>
|
||
|
such things and getting a use that is `more significant' might be<P>
|
||
|
a data abstraction violation.) In any case, the use Eliot was<P>
|
||
|
talking about really implements <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignorable"><B>IGNORABLE</B></A>, not <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A>.<P>
|
||
|
<P>
|
||
|
- There was some exploration into the area of whether <A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> should<P>
|
||
|
create a new binding every time. RPG cited that the current <P>
|
||
|
definition of <A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> is unintuitive to users of parallel lisps.<P>
|
||
|
Dalton pointed out that if a new binding were made every time, then<P>
|
||
|
the internal variable which <A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> stepped could be a different <P>
|
||
|
one, and hence the user's variable would be unused as a matter of<P>
|
||
|
course (i.e., without WITH-INVISIBLE-REFERENCES) since no hidden<P>
|
||
|
operations on it would be needed. Bob Kerns (RWK at ILA) said that<P>
|
||
|
if people were intending to close over an iteration variable, their<P>
|
||
|
intent would still be clearer if they wrote<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I N) (<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((I I)) (SPAWN #'(<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> () ...I...))))<P>
|
||
|
rather than just <P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> (I N) (SPAWN #'(<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> () ...I...)))<P>
|
||
|
<P>
|
||
|
- Dalton raised the question of whether all this trouble was really<P>
|
||
|
worth it and whether we shouldn't just specify the expansion of<P>
|
||
|
<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> precisely so users could just know what it would have going<P>
|
||
|
on inside it. RPG said ``Using possible macro expansions to reason<P>
|
||
|
about language design is poor methodology. <A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> should be<P>
|
||
|
specified and its implementation choices outlined.'' Barmar<P>
|
||
|
defended (as an example) the Symbolics implementation which<P>
|
||
|
expands differently depending on the situation and worried that<P>
|
||
|
optimizations would be harder if the expansion was dictated. The<P>
|
||
|
idea of showing a space of possible expansions was also discussed<P>
|
||
|
by RWK and others. Barmar said ``By specifying each<P>
|
||
|
operator as independently as possible we have less trouble with<P>
|
||
|
strange interactions.'' Dalton responded ``Except where we don't,<P>
|
||
|
as with <A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A> and <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A>. Moreover, it is at least arguable that<P>
|
||
|
when too much is separate the language is more complex and harder<P>
|
||
|
to learn.''<P>
|
||
|
<P>
|
||
|
- Neil Goldman cited three examples of problem situations--<P>
|
||
|
- 1) in <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> lists, because a function is used in a role<P>
|
||
|
where it may be passed arguments it does not need.<P>
|
||
|
2) <A REL=DEFINITION HREF="../Body/m_mult_2.htm#multiple-value-setq"><B>multiple-value-setq</B></A>, where the values that need to be<P>
|
||
|
consumed are not just an initial sequence of those returned.<P>
|
||
|
3) macros (like <A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>DOTIMES</B></A>), that <A REL=DEFINITION HREF="../Body/f_provid.htm#require"><B>require</B></A> the provision of a<P>
|
||
|
variable name that will be lexically bound in the expansion <P>
|
||
|
and permit <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignore"><B>IGNORE</B></A> declarations about it.<P>
|
||
|
He suggested that the form of destructuring used by <A REL=DEFINITION HREF="../Body/m_loop.htm#loop"><B>LOOP</B></A> would<P>
|
||
|
solve these problems. e.g.,<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>defun</B></A> arg1-is-integer (arg1 <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>nil</B></A>) ...) ;;second arg is <A REL=DEFINITION HREF="../Body/a_not.htm#not"><B>not</B></A> consumed<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>defun</B></A> CAR-is-integer ((<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> . <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>nil</B></A>)) ...)<P>
|
||
|
;; first arg must be a <A REL=DEFINITION HREF="../Body/a_cons.htm#cons"><B>CONS</B></A>. Its <A REL=DEFINITION HREF="../Body/f_car_c.htm#cdr"><B>CDR</B></A> is not consumed<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_mult_2.htm#multiple-value-setq"><B>multiple-value-setq</B></A> ((onea oneb) <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>nil</B></A> three) ...)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_dotime.htm#dotimes"><B>dotimes</B></A> (<A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>nil</B></A> n) (<A REL=DEFINITION HREF="../Body/m_push.htm#push"><B>push</B></A> 0 l))<P>
|
||
|
Peter Norvig (at Berkeley) worried about ambiguities in this notation.<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>defun</B></A> optional-CAR-is-integer (<A REL=DEFINITION HREF="../Body/03_da.htm#AMoptional"><B>&optional</B></A> (<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>nil</B></A>)) ...)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_defmet.htm#defmethod"><B>defmethod</B></A> CAR-is-integer ((<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> <A REL=DEFINITION HREF="../Body/a_cons.htm#cons"><B>cons</B></A>)) ...)<P>
|
||
|
<P>
|
||
|
RWK wrote one particular message which Moon identified in mail as the<P>
|
||
|
most important message in the long conversation and which Moon said he<P>
|
||
|
hoped wouldn't get lost. GLS sent mail saying he agreed. The <P>
|
||
|
message was long, but it was a good message, so KMP has picked some choice <P>
|
||
|
paragraphs from it and reproduced them here. These are from the <P>
|
||
|
message of 26 Jul 90 21:26 EDT from RWK@FUJI.ILA.Dialnet.Symbolics.COM:<P>
|
||
|
<P>
|
||
|
``Variable semantics is a very fundamental aspect of the language, <P>
|
||
|
and we have failed to specify an important part of it. Traditionally,<P>
|
||
|
we have dismissed "style warnings" as being an "environment" issue.<P>
|
||
|
However, in this case, I do not think it should be so dismissed.<P>
|
||
|
Currently, we have implementations of CL which vocally complain about<P>
|
||
|
opposite usages. Having bogus style warnings go off in this way is<P>
|
||
|
a serious problem for people porting code, because it obscures <P>
|
||
|
legitimate problems. Bogus warnings are a serious waste of time for<P>
|
||
|
porters of code, and they also make venders of portable code look as<P>
|
||
|
if they are careless programmers.<P>
|
||
|
<P>
|
||
|
``I strongly feel that a well-written portable Common Lisp program <P>
|
||
|
should compile with no warnings in any well-done Common Lisp <P>
|
||
|
implementation. Otherwise, how is the user of a portable program <P>
|
||
|
supposed to know if the warnings warn of actual problems, or are <P>
|
||
|
just noise.<P>
|
||
|
<P>
|
||
|
``I strongly feel that X3J13 should firmly nail down under what <P>
|
||
|
circumstances "unused variable" and "unused local function"<P>
|
||
|
warnings may be issued. It is our failure to do so which is<P>
|
||
|
at the heart of the current issue, and as a porter of code, it<P>
|
||
|
has been a recurrent problem.''<P>
|
||
|
<P>
|
||
|
``There are also two capabilities which are missing, which have<P>
|
||
|
been refered to as an <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignorable"><B>IGNORABLE</B></A> declaration and a <P>
|
||
|
COMPILER:INVISIBLE-REFERENCES form, in BARMAR's message. I <P>
|
||
|
actually think that both are needed. <A REL=DEFINITION HREF="../Body/d_ignore.htm#ignorable"><B>IGNORABLE</B></A> states that it<P>
|
||
|
doesn't matter if the user doesn't reference a variable. <P>
|
||
|
COMPILER:INVISIBLE-REFERENCES (WITHOUT-REFERENCES ?) states that <P>
|
||
|
the user is *expected* to reference a particular variable, and <P>
|
||
|
that style warnings are appropriate if he does not.<P>
|
||
|
<P>
|
||
|
``I think both situations are common in macros, and that because<P>
|
||
|
these issues are so close to the core of the language semantics,<P>
|
||
|
this should be regarded as something more than mere "style<P>
|
||
|
warnings". I wouldn't <A REL=DEFINITION HREF="../Body/f_provid.htm#require"><B>require</B></A> compilers and interpreters to <P>
|
||
|
issue the warnings in any particular situation, but I do think<P>
|
||
|
we can and should define the semantics of our variables sufficiently <P>
|
||
|
to state when these warnings are and are not appropriate.<P>
|
||
|
<P>
|
||
|
``I'd also like to see all of these extended to local functions<P>
|
||
|
in the same manner as the <A REL=DEFINITION HREF="../Body/d_dynami.htm#dynamic-extent"><B>DYNAMIC-EXTENT</B></A> declaration.''<P>
|
||
|
<P>
|
||
|
Pitman notes the following bug report, received by Symbolics. One very<P>
|
||
|
important effect of solving this issue is that vendors will know what<P>
|
||
|
to implement and users will know what to expect. Right now, vendors<P>
|
||
|
are forced to implement their conscience, and they have no defense if<P>
|
||
|
a user thinks they did the wrong thing. <P>
|
||
|
<P>
|
||
|
Date: Fri, 14 Sep 90 17:45 EDT<P>
|
||
|
From: J.P. Massar <massar@Think.COM><P>
|
||
|
Subject: Stupid warnings<P>
|
||
|
To: bug-lispm@Think.COM<P>
|
||
|
<P>
|
||
|
Look at all this crap. I don't care what anyone says about <P>
|
||
|
how iteration variables REALLY aren't been used...<P>
|
||
|
<P>
|
||
|
I JUST DON'T WANT TO SEE THESE STUPID MESSAGES <A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>AND</B></A> I DON'T<P>
|
||
|
PARTICULARLY FEEL LIKE GOING <A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>AND</B></A> PUTTING STUPID #+ WHATEVER's<P>
|
||
|
OVER THIS CODE.<P>
|
||
|
<P>
|
||
|
SYMBOLICS SHOULD BE SHOT FOR ISSUING THIS <A REL=DEFINITION HREF="../Body/e_warnin.htm#warning"><B>WARNING</B></A>.<P>
|
||
|
...<P>
|
||
|
<P>
|
||
|
The only little problem is--all Symbolics did was implement what it<P>
|
||
|
felt CLtL said to implement. What the user is really complaining<P>
|
||
|
about is that the implementation didn't do the same thing as he <P>
|
||
|
expected, and the only way it ever will is if we resolve this issue<P>
|
||
|
once and for all.<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>
|