461 lines
29 KiB
HTML
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 <true> if its argument can be determined by the<P>
|
|
<implementation> to be a <constant form>; otherwise, <P>
|
|
it returns <false>.<P>
|
|
<P>
|
|
The following items are considered constant forms:<P>
|
|
<P>
|
|
* <constant objects> (such as <numbers>, <characters>, and<P>
|
|
the various kinds of <arrays>) are always considered<P>
|
|
<constant forms>.<P>
|
|
<P>
|
|
* <constant variables>, such as <keywords>, 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 <constant forms>.<P>
|
|
<P>
|
|
* <A REL=DEFINITION HREF="../Body/s_quote.htm#quote"><B>QUOTE</B></A> <forms> are considered <constant forms>.<P>
|
|
<P>
|
|
* an <implementation> is permitted to, but not required to,<P>
|
|
detect additional <constant forms>. 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 <constant form> says:<P>
|
|
<P>
|
|
constant form n. any <form> for which <evaluation> <P>
|
|
always <yields> the same <value> and which neither<P>
|
|
affects nor is affected by the <environment> in which <P>
|
|
it is <evaluated>.<P>
|
|
<P>
|
|
[Loosemore has criticized this definition as being overly vague on the<P>
|
|
issue of whether a <constant form> 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 "optimizations". <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 <constant form>.<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>
|
|
<constant form>.<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 <constant form> 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 <constant form> 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>&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>&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 &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>&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>&whole</B></A> form <A REL=DEFINITION HREF="../Body/03_da.htm#AMrest"><B>&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 "obvious" 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 <symbolic-constant>)). 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 "Keep it up!"<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>
|