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

461 lines
29 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 CONSTANTP-DEFINITION 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/iss083_w.htm">
<LINK REL=UP HREF="../Issues/iss084.htm">
<LINK REL=NEXT HREF="../Issues/iss085_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/iss083_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="../Issues/iss084.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="../Issues/iss085_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
<HR>
<H2>Issue CONSTANTP-DEFINITION Writeup</H2>
<PRE><B>Issue:</B> <A HREF="iss084.htm">CONSTANTP-DEFINITION</A><P>
<B>References:</B> <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> (p324)<P>
Related issues: <A HREF="iss085.htm">CONSTANTP-ENVIRONMENT</A><P>
<A HREF="iss340.htm">SYMBOL-MACROS-AND-PROCLAIMED-SPECIALS</A><P>
<B>Category:</B> CLARIFICATION/CHANGE<P>
<B>Edit history:</B> v1, 07 Mar 1991, Sandra Loosemore<P>
v2, 12 Mar 1991, Kent Pitman<P>
v3, 14 Mar 1991, Sandra Loosemore<P>
<P>
<B>Problem description:<P>
</B><P>
The specification of <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> in CLtL says:<P>
<P>
<A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> object [Function]<P>
<P>
If the predicate <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> is true of an object, then that object,<P>
when considered as a form to be evaluated, always evaluates to the<P>
same thing; it is a constant. This includes self-evaluating objects<P>
such as numbers, characters, strings, bit-vectors and keywords,<P>
as well as constant symbols declared by <A REL=DEFINITION HREF="../Body/m_defcon.htm#defconstant"><B>DEFCONSTANT</B></A>, such as<P>
<A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>, T, and <A REL=DEFINITION HREF="../Body/v_pi.htm#pi"><B>PI</B></A>. In addition, a list whose <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> is <A REL=DEFINITION HREF="../Body/s_quote.htm#quote"><B>QUOTE</B></A>, such as<P>
(<A REL=DEFINITION HREF="../Body/s_quote.htm#quote"><B>QUOTE</B></A> FOO), is considered to be constant.<P>
<P>
If <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> is false of an object, then that object, considered<P>
as a form, might or might not always evaluate to the same thing.<P>
<P>
Some have interpreted this definition to mean what the first sentence<P>
says, with the rest of the definition being merely an elaboration.<P>
<P>
Others have interpreted that the definition seeks to identify a <P>
specific set of things which are considered to be constants for the<P>
purpose of this function, namely<P>
* a self-evaluating object<P>
* a symbol naming a defined constant (built-in or declared by <A REL=DEFINITION HREF="../Body/m_defcon.htm#defconstant"><B>DEFCONSTANT</B></A>)<P>
* a list whose <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> is the symbol <A REL=DEFINITION HREF="../Body/s_quote.htm#quote"><B>QUOTE</B></A><P>
<P>
Most implementors have implemented tests only for these specific items<P>
although there is little first-hand evidence about whether this was<P>
because they felt restricted from implementing other cases or whether<P>
they just didn't have the ambition to think up or implement additional<P>
cases. At least one implementor has implemented a small number of <P>
additional cases.<P>
<P>
Some users have assumed that this was an exhaustive list of the<P>
situations for which <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> must return true, and have written code<P>
which purports to depend on that fact.<P>
<P>
Some users have assumed that this was not an exhaustive list of the<P>
situations for which <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> must return true, and have written code<P>
which would perform better if other kinds of constant forms were <P>
detectable as well.<P>
<P>
Of the two authors of this proposal, neither Pitman nor Loosemore<P>
believes there is an ambiguity, but their opinions diverge. And since<P>
users and implementors have in good faith interpreted this wording<P>
differently, then by definition there must be an ambiguity.<P>
<P>
<B>Terminology:<P>
</B><P>
For the purposes of this discussion, a `simple constant form' will<P>
be defined as the union of these three items:<P>
* a self-evaluating object<P>
* a symbol naming a defined constant (built-in or declared by <A REL=DEFINITION HREF="../Body/m_defcon.htm#defconstant"><B>DEFCONSTANT</B></A>)<P>
* a list whose <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> is the symbol <A REL=DEFINITION HREF="../Body/s_quote.htm#quote"><B>QUOTE</B></A><P>
<P>
<B>Background:<P>
</B> <P>
The description of <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> in the draft <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A> (version 8.81) <P>
contained a bug because it did not acknowledge that (<A REL=DEFINITION HREF="../Body/s_quote.htm#quote"><B>QUOTE</B></A> xxx) would<P>
reliably be detected as a constant by <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A>. The amended text of<P>
the definition, which is the current definition in the draft <P>
specification at the time this proposal is written, says:<P>
<P>
<A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> object [Function]<P>
<P>
Returns &lt;true&gt; if its argument can be determined by the<P>
&lt;implementation&gt; to be a &lt;constant form&gt;; otherwise, <P>
it returns &lt;false&gt;.<P>
<P>
The following items are considered constant forms:<P>
<P>
* &lt;constant objects&gt; (such as &lt;numbers&gt;, &lt;characters&gt;, and<P>
the various kinds of &lt;arrays&gt;) are always considered<P>
&lt;constant forms&gt;.<P>
<P>
* &lt;constant variables&gt;, such as &lt;keywords&gt;, symbols defined<P>
by Common Lisp as constant (such as <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>, T, and <A REL=DEFINITION HREF="../Body/v_pi.htm#pi"><B>PI</B></A>),<P>
and symbols defined by the user as constant using <A REL=DEFINITION HREF="../Body/m_defcon.htm#defconstant"><B>DEFCONSTANT</B></A><P>
are always considered &lt;constant forms&gt;.<P>
<P>
* <A REL=DEFINITION HREF="../Body/s_quote.htm#quote"><B>QUOTE</B></A> &lt;forms&gt; are considered &lt;constant forms&gt;.<P>
<P>
* an &lt;implementation&gt; is permitted to, but not required to,<P>
detect additional &lt;constant forms&gt;. Examples of such forms<P>
that might be detected are: (<A REL=DEFINITION HREF="../Body/f_sqrt_.htm#sqrt"><B>SQRT</B></A> <A REL=DEFINITION HREF="../Body/v_pi.htm#pi"><B>PI</B></A>), (+ 3 2),<P>
(<A REL=DEFINITION HREF="../Body/f_length.htm#length"><B>LENGTH</B></A> '(A B C)), and (<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((X 7)) (<A REL=DEFINITION HREF="../Body/f_zerop.htm#zerop"><B>ZEROP</B></A> X)).<P>
<P>
The glossary definition of &lt;constant form&gt; says:<P>
<P>
constant form n. any &lt;form&gt; for which &lt;evaluation&gt; <P>
always &lt;yields&gt; the same &lt;value&gt; and which neither<P>
affects nor is affected by the &lt;environment&gt; in which <P>
it is &lt;evaluated&gt;.<P>
<P>
[Loosemore has criticized this definition as being overly vague on the<P>
issue of whether a &lt;constant form&gt; may affect or be affected by<P>
the objects accessible in that environment. Pitman says this is<P>
just an oversight.]<P>
<P>
At issue is both whether these descriptions accurately capture the<P>
intent of CLtL, and whether even if they do, the definition should<P>
be amended.<P>
<P>
<P>
<B>Proposal (CONSTANTP-DEFINITION:EXACT):<P>
</B><P>
Clarify that <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> returns true if and only if its argument is<P>
a `simple constant form' (see definition above).<P>
<P>
Rationale:<P>
<P>
<A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> is typically used to implement some simple kinds of<P>
code motion optimizations and side-effects analysis, for example<P>
in computing the expansion of a macro or <A REL=DEFINITION HREF="../Body/f_docume.htm#compiler-macro"><B>compiler-macro</B></A>. Permitting<P>
<A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> to return false for the three situations listed would<P>
inhibit these kinds of optimizations in the obvious situations<P>
where they were intended to be applied. Permitting <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> to <P>
return true in other situations could cause these applications to<P>
perform semantically invalid &quot;optimizations&quot;. <P>
<P>
There is also a compatibility problem if <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> is permitted to<P>
be sensitive to the lexical environment in which the form appears <P>
(see the cost to users section below).<P>
<P>
<P>
<B>Proposal (CONSTANTP-DEFINITION:INTENTIONAL):<P>
</B><P>
1. Clarify that if the predicate <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> is true of an object, <P>
then that object, when considered as a form to be evaluated, <P>
is a &lt;constant form&gt;.<P>
<P>
2. Clarify that if <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> is false of an object, then that<P>
object, considered as a form, might or might not be a<P>
&lt;constant form&gt;.<P>
<P>
3. a. Clarify that the other text in CLtL's definition of <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> <P>
is intended only as examples and to outline a minimal level<P>
of expectation for users. Explicitly permit implementations <P>
of <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> to return true for additional situations not listed<P>
among those examples, but which satisfy (1).<P>
<P>
b. Clarify that among the actions which an implementation is <P>
permitted to take is to macro expand and to do function <P>
inlining, but not to do expansion of compiler macros.<P>
<P>
4. a. Clarify that execution of a &lt;constant form&gt; neither affects nor <P>
is affected by the run-time environment, except that it is <P>
sensitive to the presence of <A REL=DEFINITION HREF="../Body/m_defcon.htm#defconstant"><B>DEFCONSTANT</B></A>.<P>
<P>
b. Clarify that execution of a &lt;constant form&gt; neither affects nor <P>
is affected by either the state of any object except those objects <P>
which are otherwise inaccessible parts of objects created by the <P>
form itself.<P>
<P>
That is, a form for which <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> previously returned <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> <P>
might at some point return T, but not vice versa.<P>
<P>
Rationale:<P>
<P>
Paragraphs (1) and (2) of this proposal are taken word-for-word<P>
from CLtL (with the appropriate substitution to the new glossary<P>
term) and Pitman thinks they speak for themselves.<P>
<P>
<P>
<B>Proposal (CONSTANTP-DEFINITION:ADD-ARGUMENT):<P>
</B><P>
Add an optional SIMPLE-P argument to <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A>, which defaults to T.<P>
[Any effect of issue CONSTANT-ENVIRONMENT is assumed to precede the<P>
effect of this issue, so unless the ENVIRONMENT argument proposed <P>
by that issue would precede the SIMPLE-P argument proposed here.]<P>
<P>
Define that if the SIMPLE-P argument is true, <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> <P>
behaves according to proposal EXACT, and that otherwise <P>
it behaves according to proposal INTENTIONAL.<P>
<P>
Rationale:<P>
<P>
This permits <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> to satisfy both needs, and allows programmers<P>
to make their intent clear.<P>
<P>
<P>
<B>Proposal (CONSTANTP-DEFINITION:RENAME):<P>
</B><P>
Rename <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> to SIMPLE-CONSTANT-FORM-P.<P>
<P>
Clarify that SIMPLE-CONSTANT-FORM-P returns true if and only if its argument<P>
is one of the three kinds of things listed in the problem description.<P>
<P>
Rationale:<P>
<P>
This doesn't preclude an extension named <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> which does<P>
more work to recognize other kinds of constant forms.<P>
<P>
<P>
<B>Proposal (CONSTANTP-DEFINITION:EXTEND-SLIGHTLY):<P>
</B><P>
Extend the definition of `simple constant form' to include a fourth case:<P>
(<A REL=DEFINITION HREF="../Body/a_values.htm#values"><B>VALUES</B></A> x1 x2 ... xN)<P>
where every xI is a `simple constant form.'<P>
<P>
<B>Test Cases:<P>
</B><P>
These cases are not evaluable forms, but rather objects that are<P>
offered as arguments to the indicated functionality:<P>
<P>
#1: 37<P>
<P>
True under all proposals. This is self-evaluating and hence<P>
a `simple constant form'.<P>
<P>
#2: <A REL=DEFINITION HREF="../Body/v_pi.htm#pi"><B>PI</B></A><P>
<P>
True under all proposals. This is the name of a defined constant<P>
and hence a `simple constant form'.<P>
<P>
#3: 'FOO<P>
<P>
True under all proposals. This is a <A REL=DEFINITION HREF="../Body/s_quote.htm#quote"><B>QUOTE</B></A> form and hence a <P>
`simple constant form.'<P>
<P>
#4: (<A REL=DEFINITION HREF="../Body/a_values.htm#values"><B>VALUES</B></A> 37 <A REL=DEFINITION HREF="../Body/v_pi.htm#pi"><B>PI</B></A> 'FOO)<P>
<P>
True under proposals EXACT, INTENTIONAL, ADD-ARGUMENT, and RENAME<P>
iff proposal EXTEND-SLIGHTLY is also adopted. Otherwise, false.<P>
<P>
#5: (<A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>PROGN</B></A> <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>)<P>
<P>
Might be either true or false under proposal INTENTIONAL, or under<P>
proposal ADD-ARGUMENT when the SIMPLE-P argument is true. Otherwise,<P>
must return false.<P>
<P>
#6: ;after a non-macro/non-inline <A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> of START-WW-III<P>
(<A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>PROGN</B></A> (START-WW-III) <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>) <P>
<P>
False under all proposals.<P>
<P>
#7: (<A REL=DEFINITION HREF="../Body/f_sqrt_.htm#sqrt"><B>SQRT</B></A> <A REL=DEFINITION HREF="../Body/v_pi.htm#pi"><B>PI</B></A>)<P>
<P>
Might be either true or false under proposal INTENTIONAL, or under<P>
proposal ADD-ARGUMENT when the SIMPLE-P argument is true. Otherwise,<P>
must return false.<P>
<P>
#7: (<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((X 7)) (<A REL=DEFINITION HREF="../Body/f_zerop.htm#zerop"><B>ZEROP</B></A> X))<P>
<P>
Might be either true or false under proposal INTENTIONAL, or under<P>
proposal ADD-ARGUMENT when the SIMPLE-P argument is true. Otherwise,<P>
must return false.<P>
<P>
#8: ;after (<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> FOO () 37)<P>
(FOO) <P>
<P>
Might be either true or false under proposal INTENTIONAL, or under<P>
proposal ADD-ARGUMENT when the SIMPLE-P argument is true. Otherwise,<P>
must return false.<P>
<P>
#9: ;in (<A REL=DEFINITION HREF="../Body/s_symbol.htm#symbol-macrolet"><B>SYMBOL-MACROLET</B></A> ((FOO <A REL=DEFINITION HREF="../Body/v_most_p.htm#most-positive-fixnum"><B>MOST-POSITIVE-FIXNUM</B></A>)) ...)<P>
FOO<P>
<P>
Might be either true or false under proposal INTENTIONAL, or under<P>
proposal ADD-ARGUMENT when the SIMPLE-P argument is true. Otherwise,<P>
must return false.<P>
<P>
#10: (<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((X (<A REL=DEFINITION HREF="../Body/a_cons.htm#cons"><B>CONS</B></A> 'X 'Y))) (<A REL=DEFINITION HREF="../Body/f_car_c.htm#cdr"><B>CDR</B></A> (<A REL=DEFINITION HREF="../Body/f_rplaca.htm#rplaca"><B>RPLACA</B></A> X 'Z)))<P>
<P>
Might be either true or false under proposal INTENTIONAL, or under<P>
proposal ADD-ARGUMENT when the SIMPLE-P argument is true. Otherwise,<P>
must return false.<P>
<P>
<P>
<B>Current Practice:<P>
</B><P>
Utah Common Lisp, KCL, CMU Common Lisp, Chestnut's Lisp-to-C<P>
translator, and IIM all implement proposal EXACT (and proposal<P>
INTENTIONAL, since it is compatible).<P>
<P>
Symbolics Genera implements proposal EXACT+EXTEND-SLIGHTLY<P>
(and proposal INTENTIONAL, since it is compatible), except<P>
that (<A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> ''(#,X)) returns <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>. The implementors indicate<P>
that the intent was to implemention INTENTIONAL and that so far<P>
they've just been busy with other things.<P>
<P>
From empirical observation, it appears that Lucid and Allegro also<P>
implement proposal EXACT (and proposal INTENTIONAL, since it is<P>
compatible).<P>
<P>
<P>
<B>Cost to Implementors:<P>
</B><P>
Very small. Here's a portable definition of <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> that<P>
conforms with proposal RENAME:<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>defun</B></A> simple-constant-form-p (x <A REL=DEFINITION HREF="../Body/03_da.htm#AMoptional"><B>&amp;optional</B></A> env)<P>
(<A REL=DEFINITION HREF="../Body/m_cond.htm#cond"><B>cond</B></A> ((<A REL=DEFINITION HREF="../Body/f_symbol.htm#symbolp"><B>symbolp</B></A> x) (<A REL=DEFINITION HREF="../Body/f_eq.htm#eq"><B>eq</B></A> (variable-information x env) :constant))<P>
((<A REL=DEFINITION HREF="../Body/f_consp.htm#consp"><B>consp</B></A> x) (<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_quote.htm#quote"><B>quote</B></A>))<P>
(t t)))<P>
<P>
Proposal EXTEND-SLIGHTLY modifies that definition in this way:<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>defun</B></A> simple-constant-form-p (x <A REL=DEFINITION HREF="../Body/03_da.htm#AMoptional"><B>&amp;optional</B></A> env)<P>
(<A REL=DEFINITION HREF="../Body/m_cond.htm#cond"><B>cond</B></A> ((<A REL=DEFINITION HREF="../Body/f_symbol.htm#symbolp"><B>symbolp</B></A> x) (<A REL=DEFINITION HREF="../Body/f_eq.htm#eq"><B>eq</B></A> (variable-information x env) :constant))<P>
((<A REL=DEFINITION HREF="../Body/f_consp.htm#consp"><B>consp</B></A> x) (<A REL=DEFINITION HREF="../Body/a_or.htm#or"><B>or</B></A> (<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_quote.htm#quote"><B>quote</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>and</B></A> (<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/a_values.htm#values"><B>values</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/f_everyc.htm#every"><B>every</B></A> #'simple-constant-form-p (<A REL=DEFINITION HREF="../Body/f_car_c.htm#cdr"><B>cdr</B></A> x)))))<P>
(t t)))<P>
<P>
<P>
<B>Cost to Users:<P>
</B><P>
If there are user programs that depend on <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> recognizing <P>
either more than just `simple constant forms' <A REL=DEFINITION HREF="../Body/a_or.htm#or"><B>OR</B></A> only<P>
`simple constant forms' they're already nonportable.<P>
<P>
The portable uses of <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> currently include those which depend<P>
on it returning true for `simple constant forms' but which are not<P>
hurt by it returning true for other kinds of constant forms.<P>
<P>
Many applications that now use <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> assume that the value it returns<P>
is not sensitive to the lexical environment in which the form appears.<P>
(Since <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> has <A REL=DEFINITION HREF="../Body/a_not.htm#not"><B>not</B></A> previously been specified to accept an <P>
environment argument, it is hard to see how any other interpretation<P>
could be made.) Proposals INTENTIONAL and ADD-ARGUMENT represent an <P>
incompatible change in this respect. All calls to <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> within <P>
user programs would have to be examined to see whether an environment <P>
argument must be passed. This also requires that something other than <P>
<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> (like <A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>FUNCALL</B></A> of ENCLOSE) be used to compute the value of something <P>
that is <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A>.<P>
<P>
<P>
<B>Cost of non-adoption:<P>
</B><P>
Users will be confused about what to expect.<P>
Implementors will be confused about what to implement.<P>
The editor will be frustrated by the mess that must be documented.<P>
<P>
<P>
<B>Performance impact:<P>
</B><P>
For the typical program, the performance impact is not major.<P>
<P>
However, it is conceivable that there are cases where recognizing only<P>
`simple constant forms' could have a substantial performance penalty<P>
on certain otherwise-portable uses of <A REL=DEFINITION HREF="../Body/m_define.htm#define-compiler-macro"><B>DEFINE-COMPILER-MACRO</B></A> which tried<P>
to base decisions about whether code-motion was appropriate on the return<P>
value of this function, and which found that such code motion was <P>
inhibited by this function being required to return <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> for constant<P>
forms that were not simple constant forms but that the implementation <P>
would have been capable of recognizing as constant. e.g., consider<P>
the following hypothetical example (which doesn't use &amp;environment<P>
only because the status of an environment argument to <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> is still<P>
a pending issue).<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>defun</B></A> foo (<A REL=DEFINITION HREF="../Body/03_da.htm#AMkey"><B>&amp;key</B></A> x y) (foo-positional x y))<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_define.htm#define-compiler-macro"><B>define-compiler-macro</B></A> foo (<A REL=DEFINITION HREF="../Body/03_dd.htm#AMwhole"><B>&amp;whole</B></A> form <A REL=DEFINITION HREF="../Body/03_da.htm#AMrest"><B>&amp;rest</B></A> key-value-pairs)<P>
(<A REL=DEFINITION HREF="../Body/m_cond.htm#cond"><B>cond</B></A> ((= (<A REL=DEFINITION HREF="../Body/f_length.htm#length"><B>length</B></A> key-value-pairs) 4)<P>
(<A REL=DEFINITION HREF="../Body/m_cond.htm#cond"><B>cond</B></A> ((<A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>and</B></A> (<A REL=DEFINITION HREF="../Body/f_eq.htm#eq"><B>eq</B></A> (<A REL=DEFINITION HREF="../Body/f_nth.htm#nth"><B>nth</B></A> 0 key-value-pairs) :x)<P>
(<A REL=DEFINITION HREF="../Body/f_eq.htm#eq"><B>eq</B></A> (<A REL=DEFINITION HREF="../Body/f_nth.htm#nth"><B>nth</B></A> 2 key-value-pairs) :y))<P>
`(foo-positional ,(<A REL=DEFINITION HREF="../Body/f_nth.htm#nth"><B>nth</B></A> 1 key-value-pairs)<P>
,(<A REL=DEFINITION HREF="../Body/f_nth.htm#nth"><B>nth</B></A> 3 key-value-pairs)))<P>
((<A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>and</B></A> (<A REL=DEFINITION HREF="../Body/f_eq.htm#eq"><B>eq</B></A> (<A REL=DEFINITION HREF="../Body/f_nth.htm#nth"><B>nth</B></A> 0 key-value-pairs) :y)<P>
(<A REL=DEFINITION HREF="../Body/f_eq.htm#eq"><B>eq</B></A> (<A REL=DEFINITION HREF="../Body/f_nth.htm#nth"><B>nth</B></A> 2 key-value-pairs) :x)<P>
(<A REL=DEFINITION HREF="../Body/a_or.htm#or"><B>or</B></A> (<A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>constantp</B></A> (<A REL=DEFINITION HREF="../Body/f_nth.htm#nth"><B>nth</B></A> 1 key-value-pairs))<P>
(<A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>constantp</B></A> (<A REL=DEFINITION HREF="../Body/f_nth.htm#nth"><B>nth</B></A> 3 key-value-pairs))))<P>
`(foo-positional ,(<A REL=DEFINITION HREF="../Body/f_nth.htm#nth"><B>nth</B></A> 3 key-value-pairs)<P>
,(<A REL=DEFINITION HREF="../Body/f_nth.htm#nth"><B>nth</B></A> 1 key-value-pairs)))<P>
(t form)))<P>
...))<P>
<P>
<P>
<B>Benefits:<P>
</B><P>
The cost of non-adoption is avoided: everyone can finally know<P>
what this function can be depended upon to do.<P>
<P>
<P>
<B>Esthetics:<P>
</B><P>
Having a well-defined <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> function is better than having<P>
a vague <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> function.<P>
<P>
<P>
<B>Discussion:<P>
</B><P>
Loosemore wrote and supports option EXACT.<P>
<P>
Pitman believes that the consensus among the Symbolics developers<P>
is for proposal INTENTIONAL. Regardless of the outcome of the four<P>
`main' proposals, Symbolics would prefer to see option EXTEND-SLIGHTLY<P>
passed.<P>
<P>
Loosemore notes:<P>
<P>
There is a danger with this issue in trying to make <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> into<P>
something over-complicated and over-featurized. I don't think that<P>
the original purpose of this function was to do anything more than<P>
perform some quick tests to detect the &quot;obvious&quot; situations, and<P>
trying to extend it into some kind of more sophisticated code-walking<P>
program analysis tool is likely to break more applications than it<P>
would help.<P>
<P>
In response to Pitman's urging for more leeway for <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A> to<P>
return true, JonL notes:<P>
<P>
Years ago, I suggested a function CONSTANT-EXPRESSION-P which would be<P>
modeled after the similar term in Interlisp; it would try to do the<P>
more complicated-albeit-heuristic processing to notice forms like<P>
(+ 3 (- 9 &lt;symbolic-constant&gt;)). Didn't get a lot of interest then.<P>
Although I think your last example [test case item #10] strains<P>
even our best SSC's, I would still say &quot;Keep it up!&quot;<P>
<P>
Barrett raised the issue about expansion of compiler-macros under<P>
proposal INTENTIONAL. Pitman replied:<P>
<P>
Sandra talked about the issue of needless extra hair, and I guess this<P>
is where I draw the line. The semantics of the form are fully<P>
specified without compiler macros, and I'd like to keep compiler<P>
macros packaged away in a corner without having them clutter every<P>
single operator. So it seemed simplest to just say they don't get<P>
used by <A REL=DEFINITION HREF="../Body/f_consta.htm#constantp"><B>CONSTANTP</B></A>.<P>
<P>
</PRE>
<HR>
<A REL=NAVIGATOR HREF="../Front/StartPts.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Starting Points]" SRC="../Graphics/StartPts.gif" ALIGN=Bottom></A><A REL=TOC HREF="../Front/Contents.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Contents]" SRC="../Graphics/Contents.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Master.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Index]" SRC="../Graphics/Index.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Symbol.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Symbols]" SRC="../Graphics/Symbols.gif" ALIGN=Bottom></A><A REL=GLOSSARY HREF="../Body/26_a.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Glossary]" SRC="../Graphics/Glossary.gif" ALIGN=Bottom></A><A HREF="../Front/X3J13Iss.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Issues]" SRC="../Graphics/Issues.gif" ALIGN=Bottom></A><BR>
<A REL=COPYRIGHT HREF="../Front/Help.htm#Legal"><I>Copyright 1996-2005, LispWorks Ltd. All rights reserved.</I></A><P>
</BODY>
</HTML>