Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

array are constantp ?!?!

38 views
Skip to first unread message

Pascal Bourguignon

unread,
Dec 25, 2002, 8:26:59 AM12/25/02
to

http://www.lispworks.com/reference/HyperSpec/Body/f_consta.htm says:

The following kinds of forms are considered constant forms:

* Self-evaluating objects (such as numbers, characters, and the
various kinds of arrays) are always considered constant forms
and must be recognized as such by constantp.

Clearly, an array is not a constant (for example, in clisp):

[4]> (setq a (make-array 4))
#(NIL NIL NIL NIL)
[5]> a
#(NIL NIL NIL NIL)
[6]> (constantp a)
T
[7]> (setf (aref a 1) 'a)
A
[8]> (constantp a)
T
[9]> a
#(NIL A NIL NIL)
[10]> (setq b a)
#(NIL A NIL NIL)
[11]> (setf (aref a 0) 'b)
B
[12]> b
#(B A NIL NIL)
[13]> a
#(B A NIL NIL)
[14]> (eq a b)
T


http://www.lispworks.com/reference/HyperSpec/Issues/iss084_w.htm says:

The description of CONSTANTP in the draft standard (version 8.81)
contained a bug because it did not acknowledge that (QUOTE xxx)
would reliably be detected as a constant by CONSTANTP. The amended
text of the definition, which is the current definition in the
draft specification at the time this proposal is written, says:

CONSTANTP object [Function]

Returns <true> if its argument can be determined by the
<implementation> to be a <constant form>; otherwise, it returns
<false>.

The following items are considered constant forms:


* <constant objects> (such as <numbers>, <characters>, and
the various kinds of <arrays>) are always considered
<constant forms>.


While CLtL says:

The specification of CONSTANTP in CLtL says:

CONSTANTP object [Function]

If the predicate CONSTANTP is true of an object, then that object,
when considered as a form to be evaluated, always evaluates to the
same thing; it is a constant. This includes self-evaluating
objects such as numbers, characters, strings, bit-vectors and
keywords, as well as constant symbols declared by DEFCONSTANT,
such as NIL, T, and PI. In addition, a list whose car is QUOTE,
such as (QUOTE FOO), is considered to be constant

The problem comes from the inclusion of all "self-evaluating objects"
in "simple constant forms".

...a `simple constant form' will be defined as the union of these
three items:

* a self-evaluating object
* a symbol naming a defined constant (built-in or declared by DEFCONSTANT)
* a list whose car is the symbol QUOTE


An array is not only a self-evaluating object containing
self-evaluating objects. it's actually an object containing values
(self-evaluating objects), and in such as way as to be more a list of
variable than a value but itself. That is, if we don't classify a
symbol naming a variable as a constant, we cannot classify an array
object containing a lot of variables as a constant neither. Just see
the above transcript to see that an array is a variable not a
constant!

Clearly, CLtL gives a logical definition of CONSTANTP, while HyperSpec
does not.

One could say that the intent of CONSTANTP (as hinted by it's
classification in HyperSpec under the chapter "3. The Evaluation and
Compilation", and in the cited issue:

CONSTANTP is typically used to implement some simple kinds of code
motion optimizations and side-effects analysis, for example in
computing the expansion of a macro or compiler-macro. Permitting
CONSTANTP to return false for the three situations listed would
inhibit these kinds of optimizations in the obvious situations
where they were intended to be applied. Permitting CONSTANTP to
return true in other situations could cause these applications to
perform semantically invalid "optimizations".

is not at all to predicate a constant, but to have a predicate for
something that can be handled at compile (or macro) time for
optimizing. Well, in that case, it should not be named CONSTANTP, but
perhaps something like "STUFF-THAT-CAN-BE-OPTMIZIED-P". After all, if
the standardization commitee renamed SPECIAL-FORM-P to
SPECIAL-OPERATOR-P, it could as well rename CONSTANTP to a meaningful
name.


As it is now, CONSTANTP cannot be used for much anything.


Did I miss something?


What is the current status of Common-Lisp standardization?


The most recent references to X3J13 date back to 1996, and most are
ten years old...

--
__Pascal_Bourguignon__ http://www.informatimago.com/
----------------------------------------------------------------------
There is a fault in reality. do not adjust your minds. -- Salman Rushdie

Rainer Joswig

unread,
Dec 25, 2002, 8:42:14 AM12/25/02
to
In article <87bs3aj...@thalassa.informatimago.com>,
Pascal Bourguignon <p...@informatimago.com> wrote:

> http://www.lispworks.com/reference/HyperSpec/Body/f_consta.htm says:
>
> The following kinds of forms are considered constant forms:
>
> * Self-evaluating objects (such as numbers, characters, and the
> various kinds of arrays) are always considered constant forms
> and must be recognized as such by constantp.
>
> Clearly, an array is not a constant (for example, in clisp):

Read "constant form" and "constant object" in the glossary of the
HyperSpec.

Erik Naggum

unread,
Dec 25, 2002, 11:23:34 AM12/25/02
to
* Pascal Bourguignon <p...@informatimago.com>
| Did I miss something?

Yes. Standards are prescriptive. You understand them, you adhere
to them, /then/ have your own opinions.

| What is the current status of Common-Lisp standardization?

Published.

| The most recent references to X3J13 date back to 1996, and most are
| ten years old...

Is it not wonderful? Nobody has randomly messed with the language
to fit some misunderstandings or added cruft to fit some marketing
scheme. Imagine a programming language that is /not/ a weapon in
someone else's marketing war, but is stable and has proven useful
to actual /programmers/ over a whole decade! Is it not amazing?

--
Erik Naggum, Oslo, Norway

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.

Alain Picard

unread,
Dec 25, 2002, 5:15:30 PM12/25/02
to
Erik Naggum <er...@naggum.no> writes:

> Is it not wonderful? Nobody has randomly messed with the language
> to fit some misunderstandings or added cruft to fit some marketing
> scheme. Imagine a programming language that is /not/ a weapon in
> someone else's marketing war, but is stable and has proven useful
> to actual /programmers/ over a whole decade! Is it not amazing?

Amazing, yes, but sad, too, that the world is so hopelessly confused
as to mistake this situation for moribundnessน. Ah, well, sometimes
being a lisp programmer is a bit like being Cassandra: you tell the
truth, but nobody ever believes you.

Merry Christmas!

น Well, if it's not a word, it ought to be. :-)

Erik Naggum

unread,
Dec 25, 2002, 5:46:03 PM12/25/02
to
* Alain Picard
| ¹ Well, if it's not a word, it ought to be. :-)

"Moribundity" appears to be the noun of choice.

Pascal Bourguignon

unread,
Dec 27, 2002, 11:03:00 AM12/27/02
to

Rainer Joswig <jos...@lispmachine.de> writes:

Useless:

constant n. 1. a constant form. 2. a constant variable. 3. a
constant object. 4. a self-evaluating object.

constant form n. any form for which evaluation always yields the
same value, that neither affects nor is affected by the
environment in which it is evaluated (except that it is permitted
to refer to the names of constant variables defined in the
environment), and that neither affects nor is affected by the
state of any object except those objects that are otherwise
inaccessible parts of objects created by the form itself. ``A car
form in which the argument is a quote form is a constant form.''

constant object n. an object that is constrained (e.g., by its
context in a program or by the source from which it was obtained)
to be immutable. ``A literal object that has been processed by
compile-file is a constant object.''

constant variable n. a variable, the value of which can never
change; that is, a keyword[1] or a named constant. ``The symbols
t, nil, :direction, and most-positive-fixnum are constant
variables.''

self-evaluating object n. an object that is neither a symbol nor a
cons. If a self-evaluating object is evaluated, it yields itself
as its only value. ``Strings are self-evaluating objects.''


Only self-evaluating object could be applied to arrays.
When you evaluate an array, you get the array, ok.
Only that if you evaluate an array twice, you can get a different value.

Just evaluate this if you don't believe me:

(setq a1 (make-array 2 :initial-contents '(:a :b)))
(setq a2 (make-array 2 :initial-contents a1)) ;; a1 evaluated once here
a1 ;; a1 evaluated twice here, ok, it's same
(equal a1 a2)
(setf (aref a1 0) :x)
a1 ;; a1 evaluated thrice here, oops, not the same!
(equal a1 a2)


Once again, the point is that an array is not a value, it's a list of
variables! And these variables are not constant.

And concerning the immutability of the specifications, it just means
that lisp is supple enough a language to let it's programmers ignore
awkward parts of the specifications and write their own "patches",
each and every one of us.

Pascal Bourguignon

unread,
Dec 27, 2002, 11:18:04 AM12/27/02
to

Erik Naggum <er...@naggum.no> writes:

> * Pascal Bourguignon <p...@informatimago.com>
> | Did I miss something?
>
> Yes. Standards are prescriptive. You understand them, you adhere
> to them, /then/ have your own opinions.
>
> | What is the current status of Common-Lisp standardization?
>
> Published.
>
> | The most recent references to X3J13 date back to 1996, and most are
> | ten years old...
>
> Is it not wonderful? Nobody has randomly messed with the language
> to fit some misunderstandings or added cruft to fit some marketing
> scheme. Imagine a programming language that is /not/ a weapon in
> someone else's marketing war, but is stable and has proven useful
> to actual /programmers/ over a whole decade! Is it not amazing?

In HyperSpec, there are a lot of unresolved issues. 366 to be exact.
So I find it amazing that they've not been working for ten years on
resolving them.
http://www.lispworks.com/reference/HyperSpec/Issues/I_Alpha.htm

Note that http://www.ncits.org/tc_home/j13.htm
says that:

J13 - Programming Language LISP

During 1994, J13 conducted its second public review of X3.226,
Programming Language LISP, resolved the outstanding TC negative on
the final ballot, and forwarded the dpANS for final approval.

The document was approved as an American National Standard on
December 8, 1994.

This technical committee is the U.S. TAG to ISO/IEC JTC 1
SC22/WG16 and provides recommendations on U.S. positions to the
JTC 1 TAG.

So they've just approved a document with 366 unresolved issues and
_known_ problems. I'm just pointing to another problem that does not
seem to be known yet.

> --
> Erik Naggum, Oslo, Norway
>
> Act from reason, and failure makes you rethink and study harder.
> Act from faith, and failure makes you blame someone and push harder.

--

Pascal Costanza

unread,
Dec 27, 2002, 11:30:34 AM12/27/02
to
Pascal Bourguignon wrote:
> Rainer Joswig <jos...@lispmachine.de> writes:
>
>
>>In article <87bs3aj...@thalassa.informatimago.com>,
>> Pascal Bourguignon <p...@informatimago.com> wrote:
>>
>>
>>>http://www.lispworks.com/reference/HyperSpec/Body/f_consta.htm says:
>>>
>>> The following kinds of forms are considered constant forms:
>>>
>>> * Self-evaluating objects (such as numbers, characters, and the
>>> various kinds of arrays) are always considered constant forms
>>> and must be recognized as such by constantp.
>>>
>>>Clearly, an array is not a constant (for example, in clisp):
>>
>>Read "constant form" and "constant object" in the glossary of the
>>HyperSpec.
>
>
> Useless:
[...]

> self-evaluating object n. an object that is neither a symbol nor a
> cons. If a self-evaluating object is evaluated, it yields itself
> as its only value. ``Strings are self-evaluating objects.''
>
>
> Only self-evaluating object could be applied to arrays.
> When you evaluate an array, you get the array, ok.
> Only that if you evaluate an array twice, you can get a different value.
>
> Just evaluate this if you don't believe me:
>
> (setq a1 (make-array 2 :initial-contents '(:a :b)))
> (setq a2 (make-array 2 :initial-contents a1)) ;; a1 evaluated once here
> a1 ;; a1 evaluated twice here, ok, it's same
> (equal a1 a2)
> (setf (aref a1 0) :x)
> a1 ;; a1 evaluated thrice here, oops, not the same!
> (equal a1 a2)

You didn't quite get what the term "self-evaluating" means. (make-array
...) is not an array, but it is a form that creates an array - thus, it
is not self-evaluating. #(5 6 7) is a constant that denotes an array
with the three elements 5, 6 and 7 - so this is self-evaluating: #(5 6
7) results in #(5 6 7). You're not allowed to change the contents of
such an array ("the consequences are undefined").

I hope this helps.

Pascal

--
Pascal Costanza University of Bonn
mailto:cost...@web.de Institute of Computer Science III
http://www.pascalcostanza.de Römerstr. 164, D-53117 Bonn (Germany)

Edi Weitz

unread,
Dec 27, 2002, 11:59:59 AM12/27/02
to
Pascal Bourguignon <p...@informatimago.com> writes:

> In HyperSpec, there are a lot of unresolved issues. 366 to be
> exact. So I find it amazing that they've not been working for ten
> years on resolving them.
> http://www.lispworks.com/reference/HyperSpec/Issues/I_Alpha.htm

And I find it amazing that you haven't even understood the
introduction to the CLHS but nevertheless don't hesitate to troll so
loudly here. The "unresolved" issues you're talking about were solved
by the standard, in fact, the "issues" were part of the process:

<http://www.lispworks.com/reference/HyperSpec/Front/X3J13Iss.htm>

> So they've just approved a document with 366 unresolved issues and
> _known_ problems. I'm just pointing to another problem that does
> not seem to be known yet.

Thank you very much. Could you please go somewhere else and try to
help there?

Edi.

Barry Margolin

unread,
Dec 27, 2002, 1:14:19 PM12/27/02
to
In article <87isxfp...@thalassa.informatimago.com>,

Pascal Bourguignon <p...@informatimago.com> wrote:
>In HyperSpec, there are a lot of unresolved issues. 366 to be exact.
>So I find it amazing that they've not been working for ten years on
>resolving them.

J13 has been effectively moribund since the standard was approved. At the
time that it was approved, there were only about a dozen people still
actively involved.

I think that ANSI requires that a standard be either revised or re-ratified
at least every 10 years. So if nothing is done within the next 2 years,
the Common Lisp standard will cease to exist officially.

--
Barry Margolin, bar...@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

Erik Naggum

unread,
Dec 27, 2002, 1:47:30 PM12/27/02
to
* Pascal Bourguignon

| Once again, the point is that an array is not a value, it's a list
| of variables! And these variables are not constant.

How young were when you arrived at the conclusion that you know
best and that listening to other people is a waste of your time?

| And concerning the immutability of the specifications, it just
| means that lisp is supple enough a language to let it's programmers
| ignore awkward parts of the specifications and write their own
| "patches", each and every one of us.

While you may believe that you have judged the standard and the
language and the community of users, you have instead given the
whole entire world a solid reason to judge you.

Now that you have demonstrated that you believe that knowledge can
be acquired without effort, how do you write programs? With a tap
of your magic wand, the computer just does what you want, right?

Erik Naggum

unread,
Dec 27, 2002, 2:54:39 PM12/27/02
to
* Pascal Bourguignon

| I'm just pointing to another problem that does not seem to be known
| yet.

Thank you. Without your valiant effort to teach us all, we would
not know anything. Could you hurry up the teaching part, though?
I am so curious to learn what you look like when you have run out
of things to tell people and arrive at the point when you listen to
others. You see, I am so old that I have seen teenagers who know
everything and think nobody else could possibly have discovered it
before they did so many times as to have tired of their kind.

What is so great about the Common Lisp world is that /everything/
has been discovered before you. That is to say, to be truly novel
in the Common Lisp community, you have to do a lot of /work/. You
can learn from people for 20 years and still not have learned it
all. This is what computer science was supposed to be like but is
not because of people like you: people who crave /novelty/ for its
own sake. I for one am decidely happy to have been born in a fully
evolved society so that I did not have to walk miles to get fresh
water or have to invent my own writing system and everything I value
in modern society. It probably sounds strange to you, but I /like/
not having to discover everything for myself, and so do many other
Common Lisp programmers. We do not have to start from scratch, we
do not /like/ to start from scratch every time, we think it is a
really great thing that somebody else did so much work before we
entered the scene that we can do our little part to improve our own
existence (or that of an employer) instead of having to build an
entire society from scratch to do it. And to those who do not want
to build whole societies merely in order to buy a loaf of bread, the
freedom comes with a responsibility to learn what went before, to
show a deep gratitude and respect towards those who /did/ build the
society where we can buy a loaf of bread for a dollar or two instead
of having to spend /hours/ to make one ourselves from scratch.

An even older friend of mine published a book almost 18 years ago,
with an appendix of self-framed slogans suitable for mounting, one
of which is applicable to this day. It reads

Just because you think you need steel-belted radial tires
and the store only has polyglas-belted ones at present,
is still no excuse for going off in a corner and reinventing the travois.

(Michael A. Padlipsky: The Elements of Networking Style and other
essays and animadversions on the art of intercomputer networking,
originally ISBN 0-13-268111-0, reissued ISBN 0-595-08879-1.)

A field does not become a /science/ until those who enter it do so
with the humility of wanting to learn what prior practitioners had
done both right and wrong, before they want to practice themselves.
Computer science is still not a real science because of this.

Pascal Costanza

unread,
Dec 27, 2002, 3:53:10 PM12/27/02
to
Pascal Bourguignon wrote:
> http://www.lispworks.com/reference/HyperSpec/Body/f_consta.htm says:
>
> The following kinds of forms are considered constant forms:
>
> * Self-evaluating objects (such as numbers, characters, and the
> various kinds of arrays) are always considered constant forms
> and must be recognized as such by constantp.

Perhaps some of the confusion can be avoided if you explain why you are
interested in this topic in the first place? There seems to be something
else going on...


Pascal

--
Given any rule, however ‘fundamental’ or ‘necessary’ for science, there
are always circumstances when it is advisable not only to ignore the
rule, but to adopt its opposite. - Paul Feyerabend

Kent M Pitman

unread,
Dec 27, 2002, 5:35:55 PM12/27/02
to
Barry Margolin <bar...@genuity.net> writes:

> In article <87isxfp...@thalassa.informatimago.com>,
> Pascal Bourguignon <p...@informatimago.com> wrote:
> >In HyperSpec, there are a lot of unresolved issues. 366 to be exact.

the issues in the hyperspec are resolved, not unresolved.

> >So I find it amazing that they've not been working for ten years on
> >resolving them.
>
> J13 has been effectively moribund since the standard was approved. At the
> time that it was approved, there were only about a dozen people still
> actively involved.

s/moribund/stable/



> I think that ANSI requires that a standard be either revised or re-ratified
> at least every 10 years. So if nothing is done within the next 2 years,
> the Common Lisp standard will cease to exist officially.

5 years, and it was renewed at the 5 year boundary.

although a 1994 standard, it wasn't published until 1995. i think this is
the only standard that has a full one-year lag between its name and its
publication date, and so i don't know what they decided was the right
anniversary date. in any case, it doesn't come up again until 2004 or 2005
depending on how you count, and it's improper to refer to it as moribund.

Barry Margolin

unread,
Dec 27, 2002, 6:37:50 PM12/27/02
to
In article <sfw65tf...@shell01.TheWorld.com>,

Kent M Pitman <pit...@world.std.com> wrote:
>depending on how you count, and it's improper to refer to it as moribund.

Has the committee had any meetings or taken any action in the past few
years? If there are any plans to produce a revision by 2005, I'd think
that you'd have to be starting on it now.

Even if no major changes are planned, standards committees are supposed to
respond to requests for clarifications, and those should be worked into the
next revision. I.e. if the standard were a software application, you'd be
putting out bug fixes and point releases. But you need an active committee
to do that.

Note: I didn't say that the standard was moribund, I said the *committee*
was. If it's not really dead, it's playing it well. Was the 5-year
renewal anything more than a rubber stamp?

Kenny Tilton

unread,
Dec 27, 2002, 9:39:09 PM12/27/02
to
I don't have anything to add, I've just always wanted to write an
article entitled "In Defense of Bourguignon". But seriously folks...

To be fair, it is possible PB staggered random-accessedly onto the
issues list without first encountering the "this is what we addressed"
intro, the web being what it is.

And his ensuing astonishment that nothing has been done about those for
ten years... aw c'mon, at least he was reading the CLHS! :) So what if
he squeezed off a few rounds based on incomplete understanding. (I think
that is all it was--call me charitable if you like, but you'll be the
first.) Y'all did the same with him. As far as I can make out he came as
a friend, after reading a lot about CL on slashdot or something.

All we had to do is steer him straight, not damn him to the fires
eternal. Plenty of time for that after his next article. :)

--

kenny "OpenGL still kicking my butt" tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
the bath water is cold." -- Lorraine Lee Cudmore

Pascal Bourguignon

unread,
Dec 27, 2002, 9:45:58 PM12/27/02
to

Erik Naggum <er...@naggum.no> writes:
> [blah blah blah]

In my original post, I wrote plainly, separated by two empty lines
before and after:

>
>
> Did I miss something?
>
>

You had there the occasion to enlight me and teach me. You were
silent on the subject of array/constantp, so now let me elaborate, and
let me tell you.

Kenny Tilton

unread,
Dec 27, 2002, 9:56:47 PM12/27/02
to

Pascal Bourguignon wrote:
>
> You had there the occasion to enlight me and teach me. You were
> silent on the subject of array/constantp, so now let me elaborate, and
> let me tell you.

Was there supposed to be more after this? Anyway, perhaps the confusion
here is over constant vs what I have seen called "mutable" in I believe
a C++ context. A mutable but constant array could have an array element
changed, but one could not change the array per se.

Worse, in your example you called make-array twice, creating two
different instances of array. constantp has nothing to say about that.

The only problem here, IMHO, is that you are putting your questions in
the form of statements. Slow down and ask. I have been doing C and CL,
for a while, and I myself puzzled over arrays being constantp. I would
not have made your mistake of thinking that mutating an array proved it
was not constant, but I still would not be able explain why arrays
themselves are constantp albeit mutable.

--

kenny tilton

Pascal Bourguignon

unread,
Dec 27, 2002, 10:01:55 PM12/27/02
to
Pascal Costanza <cost...@web.de> writes:

> Pascal Bourguignon wrote:
> > http://www.lispworks.com/reference/HyperSpec/Body/f_consta.htm says:
> > The following kinds of forms are considered constant forms:
> > * Self-evaluating objects (such as numbers, characters, and the
> > various kinds of arrays) are always considered constant forms
> > and must be recognized as such by constantp.
>
> Perhaps some of the confusion can be avoided if you explain why you
> are interested in this topic in the first place? There seems to be
> something else going on...
>
>
> Pascal

I like standards and well defined languages because of the portability
they allow. Contrarily to what some here seem to have infered from my
posts I'm in computers long enough to appreciate not having to rewrite
all my applications from scratch each time I changed hardware and
software platforms.


Right now, I'm scanning HyperSpec and trying to implement missing
COMMON-LISP functions on emacs, to allow me to use COMMON-LISP
programs both in clisp and in emacs. While I will keep to write LISP
code for emacs, I'd like to make it as COMMON-LISP as possible and
have as little dependencies on emacs as possible.

So, my interest is half that of an implemented and half that of a user
of COMMON-LISP who needs a precisely defined specifications to be able
to develop portable COMMON-LISP programs.

Now, concerning CONSTANTP, and if the delicate people reading this
would mind adding a "IMHO" on each line of the following:

The problem with CONSTANTP comes from an incoherency in the
specifications (HyperLisp).

First, in section "2.4.8.12 Sharpsign A" it's explained how a
standardized reader macro can be used to build an array, making an
explicit reference to MAKE-ARRAY.


The signature of MAKE-ARRAY is:

MAKE-ARRAY dimensions &key element-type initial-element
initial-contents adjustable fill-pointer displaced-to
displaced-index-offset

and you can see that there is no parameter specifying whether the
array built must be mutable or immutable.


Similarly, section "2.4.5 Double-Quote" explains how a STRING can be
read, with no explicit reference to MAKE-STRING, and with no
indication that so-built strings must be immutable or not.

Idem for lists (conses builts automatically when ( a b c d ) is read),
vectors #(...), structures #S(...), not to speak of #. and #P !

More over, if #. and #P were not enough, there is provisions in the
standard to let the user add his own reader macros.

So we can have textual forms for any kind of objets from simple
integers to complicated agregate structures, of which all agregates,
when translated to S-expr must be detected as immutable by CONSTANTP,
_BUT_ there is no notion of mutable/immutable in COMMON-LISP.


While there is a tentative approach to the immutable concept:

immutable adj. not subject to change, either because no operator
is provided which is capable of effecting such change or because
some constraint exists which prohibits the use of an operator that
might otherwise be capable of effecting such a change. Except as
explicitly indicated otherwise, implementations are not required
to detect attempts to modify immutable objects or cells; the
consequences of attempting to make such modification are
undefined. ``Numbers are immutable.''

it is not enough.

Clearly, it's lacking a (SET-IMMUTABLE object) function and a
(IMMUTABLEP object) predicate to at least make a newly created by
default mutable object immutable. These functions could be used by
the reader macro functions and by CONSTANTP to correctly implement the
required semantics.

SET-IMMUTABLE would have to be called on all cons made by the reader
macro of lists. (Of course, a specific implementation of the reader
could optimize this and have a (CONS-IMMUTABLE car cdr) primitive).
This SET-IMMUTABLE function could then be used by user-defined reader
macros and user functions written in #. to keep the wanted semantics.


<nagging>
While the LISP standardization commitee was sleeping in their coffins,
other languages evolved and precised and implemented this notion of
immutability. For example, Objective-C, if only at the class library
level, but with some integration to the language, where @"string", the
readable form of a literal string object is explicitely specified to
create an immutable string instance. And if IIRC, Java has something
to say about immutability too.
</nagging>

Here is what we get with clisp, which I'm affraid is according to the
standard unfortunately:

[17]> (constantp #1A( :toto 12 ))
T ;; this is correct

[18]> (setq a (make-array 2 :initial-contents '(:toto 12)))
#(:TOTO 12)
[19]> (constantp a)
T ;; this is not correct!
[20]> (setf (aref a 0) :titi)
:TITI
[21]> a
#(:TITI 12) ;; see! A is not constant !
[22]> (constantp a)
T


[37]> (setq a "toto")
"toto"
[38]> (setq b a)
"toto"
[39]> (setf (aref a 1) (code-char 65))
#\A
[40]> (eq a b)
T
[41]> (constantp a)
T ;; What an infamy!!!
[42]> a
"tAto"
[43]> b
"tAto"


Perhaps users of CMU CL and the happy users of commercial
implementations of COMMON-LISP could tell us what are the results of
CONSTANTP in their LISP?

Pascal Bourguignon

unread,
Dec 27, 2002, 10:02:26 PM12/27/02
to
Edi Weitz <e...@agharta.de> writes:

> Pascal Bourguignon <p...@informatimago.com> writes:
>
> > In HyperSpec, there are a lot of unresolved issues. 366 to be
> > exact. So I find it amazing that they've not been working for ten
> > years on resolving them.
> > http://www.lispworks.com/reference/HyperSpec/Issues/I_Alpha.htm
>
> And I find it amazing that you haven't even understood the
> introduction to the CLHS but nevertheless don't hesitate to troll so
> loudly here. The "unresolved" issues you're talking about were solved
> by the standard, in fact, the "issues" were part of the process:
>
> <http://www.lispworks.com/reference/HyperSpec/Front/X3J13Iss.htm>

Ok. So they are resolved. But they are not illuminating. See my
following post about immutablility.


> > So they've just approved a document with 366 unresolved issues and
> > _known_ problems. I'm just pointing to another problem that does
> > not seem to be known yet.
>
> Thank you very much. Could you please go somewhere else and try to
> help there?

No.

> Edi.

Erik Naggum

unread,
Dec 27, 2002, 10:08:46 PM12/27/02
to
* Pascal Bourguignon

| You had there the occasion to enlight me and teach me.

I did seize the occasion, but you were both unenlightenable and
unteachable because you had set your mind to the matters about
which you could be enlightened and taught.

A student who knows so well what he is to be taught that he rejects
everything that is not to his liking is a contradiction in terms,
for it is what you do not know that you need be taught.

You had the occasion to become enlightened and taught, but remain
befuddled by your own preconceptions. Such was your choice, and
such it shall be. I wish you better luck in your next life, as the
one you have wasted so far will require many years to salvage.

A hint, though: Thinking is not the crime you believe it is.

Kent M Pitman

unread,
Dec 27, 2002, 10:56:00 PM12/27/02
to
Barry Margolin <bar...@genuity.net> writes:

> In article <sfw65tf...@shell01.TheWorld.com>,
> Kent M Pitman <pit...@world.std.com> wrote:
> >depending on how you count, and it's improper to refer to it as moribund.
>
> Has the committee had any meetings or taken any action in the past few
> years?

I'm not the one to speak on this, since I'm no long a participant;
presumably smh will chime in. But the ansewr to this, since I was
a member at the time the renewal vote was taken, is yes.

> If there are any plans to produce a revision by 2005, I'd think
> that you'd have to be starting on it now.

Right. But if there's no plan to revise it, and I think there is no such
plan, then you don't have to start now. I think personally think it an
etraordinarily bad idea to plan to revise the standard. I think the right
thing is simply to again renew it, and that requires no planning.

I think most things needing doing can be done by layered standards without
destabilizing what is there. That's just my personal opinion.

> Even if no major changes are planned, standards committees are supposed to
> respond to requests for clarifications,

If submitted in the prescribed way. Don't ask me what that way is, but
to my knowledge there have been no formal requests for that and so technically
they have responded to all such requests....

> and those should be worked into the next revision.

If there is one.

> I.e. if the standard were a software application, you'd be
> putting out bug fixes and point releases. But you need an active committee
> to do that.
>
> Note: I didn't say that the standard was moribund, I said the *committee*
> was. If it's not really dead, it's playing it well.

I, for one, had a personal membership and would have renewed my membership
either personally or for HyperMeta, when I formed it, had I felt it worthwhile.
I have come to the conclusion personally that ANSI is way too large and clumsy
and expensive a vehicle for ongoing standards work and I personally do not
plan to support it. I would rather see the community find a more agile
venue.

> Was the 5-year renewal anything more than a rubber stamp?

Not that I recall.

Pascal Bourguignon

unread,
Dec 28, 2002, 2:42:25 AM12/28/02
to
Kenny Tilton <kti...@nyc.rr.com> writes:

> Pascal Bourguignon wrote:
> > You had there the occasion to enlight me and teach me. You
> > were
> > silent on the subject of array/constantp, so now let me elaborate, and
> > let me tell you.
>
> Was there supposed to be more after this?

Yes, I elaborated in my other post "Re: array are constantp ?!?! immutability".

> Anyway, perhaps the confusion here is over constant vs what I have
> seen called "mutable" in I believe a C++ context. A mutable but
> constant array could have an array element changed, but one could
> not change the array per se.

That sounds strange. (Well, given C++, perhaps not.)

In Objective-C, and with a little common sense, what you expect from
constant stuff is to be immutable. A value can be mutable (usually it
is), or immutable thus being like a constant, only one that have been
created at run-time instead of at compile time (or lexical time if you
will). In Objective-C, the mutability or immutability status is
implemented specifically by each class. There is a NSString class
whose instances are immutable, and a NSMutableString whose instances
are mutable. When parsing: @"literal", the compiler creates an
immutable instance (of a subclass of NSString). Actually this is the
only place where the Objective-C compiler does anything special vs.
mutability/immutability, the rest is handled by the class library and
therefore independant of the language. There are similar couples for
arrays, dictionaries, etc.


> Worse, in your example you called make-array twice, creating two
> different instances of array. constantp has nothing to say about that.


True, but I would not have been, and I'm not surprised to see that

[1]> (constantp #(:a :b))
T


What's shocking me is:

[2]> (constantp (make-array 2 :initial-contents '(:a :b)))
T


This may be a bug in the implementation, but then the HyperSpec is
somewhat ambiguous, and I can see how a reading of it can lead to
implement such a behavior for CONSTANTP. CLtL does defines informally
a correct and meaningfull CONSTANTP IMHO, but this formulation is not
used in CLHS.


> The only problem here, IMHO, is that you are putting your questions in
> the form of statements.

Yes, I tend to. Sorry.

> Slow down and ask. I have been doing C and CL,
> for a while, and I myself puzzled over arrays being constantp. I would
> not have made your mistake of thinking that mutating an array proved
> it was not constant, but I still would not be able explain why arrays
> themselves are constantp albeit mutable.

So here are questions:

- what the language in CLHS means?
Should (CONSTANTP (MAKE-ARRAY 2 :INITIAL-CONTENTS '(:A :B)))
return T or NIL?

T | NIL | other, N/A
| |
Do you call the result of | Ok, so CLISP got it wrong, | Please explain?
(MAKE-ARRAY ...) a constant? | at least you must agree with |
| me on that mustn't you? |
No | Yes | |
| | But what about CLHS that |
How do you |How do you | explicitely says that |
feel that |explain that | CONSTANTP should return T |
CONSTANTP |one may modify | for array? |
returns T for |something that | |
something you |you and | Did they want to mean only |
don't call a |CONSTANTP call | for immutable arrays and |
constant? | constant? | boltched and wrote ambiguous |
| | "specifications"? |
What about my |Does it seems | |
suggestion |illogical to | Yes | No |
that the std |anybody else | | |
comitee |than me here? |Then we agree,|Please explain?|
rename that | |and since life|To me, this |
function like | |is not |would mean a |
it did for | |agradable with|big |
SPECIAL-FORM-P| |ambiguous std,|contradiction. |
? | |don't you |WHat did they |
| |agree that we |mean? Why did |
| |should rework |they not write |
| |(or add a |what they |
| |corrective |meant? |
| |layer on) CL | |
| |standard ? | |
| |For example, | |
| |introducing | |
| |set-immutable | |
| |and immutablep| |

Peter Seibel

unread,
Dec 28, 2002, 3:17:59 AM12/28/02
to
Pascal Bourguignon <p...@informatimago.com> writes:

> Pascal Costanza <cost...@web.de> writes:
>
> > Pascal Bourguignon wrote:
> > > http://www.lispworks.com/reference/HyperSpec/Body/f_consta.htm says:
> > > The following kinds of forms are considered constant forms:
> > > * Self-evaluating objects (such as numbers, characters, and the
> > > various kinds of arrays) are always considered constant forms
> > > and must be recognized as such by constantp.
> >
> > Perhaps some of the confusion can be avoided if you explain why
> > you are interested in this topic in the first place? There seems
> > to be something else going on...
>

> I like standards and well defined languages because of the
> portability they allow. Contrarily to what some here seem to have
> infered from my posts I'm in computers long enough to appreciate not
> having to rewrite all my applications from scratch each time I
> changed hardware and software platforms.

Fair enough. But I think Pascal C. was asking (and if he wasn't I
guess I am) is what sort of code are you writing that makes you wish
that CONSTANTP said something about immutability. For it seems that
CONSTANTP is pretty well defined; it just doesn't happen to mean
"immutable".

I'm not sure *what* CONSTANTP is used for in the wild but I'm willing
to assume, since my experience with Lisp is measured in months and the
spec's age is measured in years, that I may not have grasped the all
the uses of the semantics it does provide. That CONSTANTP takes an
optional environment object argument such as you get with an
&environment variable in a macro lambda list, suggests that it is
perhaps intended for use in writing clever macros that expand into
different things depending on whether various forms they are passed in
can ever change. The following macro is *not* clever but it at least
shows what I mean:

(defmacro with-no-constants (&body body &environment env)
`(progn
,@(mapcan
#'(lambda (form)
(if (constantp form env) nil (list form)))
body)))

Which gives us:

[7c] FOO(317): (macroexpand-1 '(with-no-constants 10 (foo 10) #1A(:foo)))
(PROGN (FOO 10))
T

Obviously this macro is not much use by itself as any literal code
that might be wrapped in with-no-constants would hopefully be
optimized away by the compiler anyway. But you can, perhaps, imagine
more elaborate uses of this technique.



> Right now, I'm scanning HyperSpec and trying to implement missing
> COMMON-LISP functions on emacs, to allow me to use COMMON-LISP
> programs both in clisp and in emacs. While I will keep to write LISP
> code for emacs, I'd like to make it as COMMON-LISP as possible and
> have as little dependencies on emacs as possible.
>
> So, my interest is half that of an implemented and half that of a
> user of COMMON-LISP who needs a precisely defined specifications to
> be able to develop portable COMMON-LISP programs.

A worthy goal. However reading specs is tricky stuff. The CL spec is
actually relatively pleasant as specs go because it isn't (in my
experience) full of inconsistencies and poorly thought out parts the
way most documents that pass for "specs" these days are. This high
quality allows one to adopt the strategy of saying, Hmmm, this doesn't
seem to make sense; that *probably* means that I'm still
misunderstading something or making an unfounded assumption. I would
join the others in this thread who've responded with (more or less
blunt versions of) the advice to slow down and use this strategy. You
*may* yet find some inconsistency or another in the spec (for example,
some of the non-normative example code is, I believe, buggy); you
*might* even find some deficiency that has been heretofore overlooked.
But's it's not too likely. In this case, this strategy might lead you
to consider what else, other than immutability, CONSTANTP might be
about and see if the spec snaps back into a self-consistent whole
under that interpretation.

> Now, concerning CONSTANTP, and if the delicate people reading this
> would mind adding a "IMHO" on each line of the following:
>
> The problem with CONSTANTP comes from an incoherency in the
> specifications (HyperLisp).

I think it only *seems* incoherent if you start from the idea that
CONSTANTP is supposed to say something about immutability. As far as I
can tell from my own reading of the spec is that it is more about
whether the given forms will be side-effect free. But that is, in
general, a pretty hard thing to know about an arbitrary form so the
spec--wisely, I'll bet--makes CONSTANTP a fairly weak version of "is
this form side-effect free" with room for implementors to do a better
job:

"If an implementation chooses to make use of the environment
information, such actions as expanding macros or performing function
inlining are permitted to be used, but not required"

> First, in section "2.4.8.12 Sharpsign A" it's explained how a
> standardized reader macro can be used to build an array, making an
> explicit reference to MAKE-ARRAY.
>
> The signature of MAKE-ARRAY is:
>
> MAKE-ARRAY dimensions &key element-type initial-element
> initial-contents adjustable fill-pointer displaced-to
> displaced-index-offset
>
> and you can see that there is no parameter specifying whether the
> array built must be mutable or immutable.

Right. The language designers seems to have choosen not to say a lot
about immutability except in the glossary entry you cite below. And
the key part of that entry (for this discussion) is probably: "Except


as explicitly indicated otherwise, implementations are not required to

detect attempts to modify immutable objects or cells".

> Similarly, section "2.4.5 Double-Quote" explains how a STRING can be
> read, with no explicit reference to MAKE-STRING, and with no
> indication that so-built strings must be immutable or not.
>
> Idem for lists (conses builts automatically when ( a b c d ) is read),
> vectors #(...), structures #S(...), not to speak of #. and #P !
>
> More over, if #. and #P were not enough, there is provisions in the
> standard to let the user add his own reader macros.
>
> So we can have textual forms for any kind of objets from simple
> integers to complicated agregate structures, of which all agregates,
> when translated to S-expr must be detected as immutable by CONSTANTP,
> _BUT_ there is no notion of mutable/immutable in COMMON-LISP.

I'm not sure where you get that all these forms "must be detected as
immutable by CONSTANTP". Can you point me to the part of the spec that
leads you to this conclusion? Note that CONSTANTP is about 'constant
forms' not 'constant objects'. And it's 'constant objects' that are
(according to the glossary entry) immutable.

> While there is a tentative approach to the immutable concept:
>
> immutable adj. not subject to change, either because no operator
> is provided which is capable of effecting such change or because
> some constraint exists which prohibits the use of an operator
> that might otherwise be capable of effecting such a change.
> Except as explicitly indicated otherwise, implementations are
> not required to detect attempts to modify immutable objects or
> cells; the consequences of attempting to make such modification
> are undefined. ``Numbers are immutable.''
>
> it is not enough.

Well, it's not enough if you want language support for a concept of
object immutability. Which sort of brings us back to Pascal C's
quesiton, what are you doing that this feature seems so desirable?
Given that Lisp has gotten along as long as it has without this
feature, there are probably other idioms or practices that make life
bearable without it. Or maybe this is just one of those things like
strong/static/whatever-it's-supposed-to-be-called typing that some
non-Lisp folks think is crucial and Lisp folks consider either
needless or even harmful.

> <nagging>
> While the LISP standardization commitee was sleeping in their
> coffins, other languages evolved and precised and implemented this
> notion of immutability. For example, Objective-C, if only at the
> class library level, but with some integration to the language,
> where @"string", the readable form of a literal string object is
> explicitely specified to create an immutable string instance. And if
> IIRC, Java has something to say about immutability too.
> </nagging>

I don't know about Objective C (though a quick web search seems to say
that @"string" only works for strings which is a pretty easy case).
Java doesn't have any particular support for object immutability:
Strings happen to be immutable because the String class doesn't
provide any mutators (and string literals in code are interned so
that:

new String("foo").intern() == "foo"

should always be true. But there's no programatic way to determine
that Strings, or instances any other class, happen to be immutable.
Which doesn't seem to matter a lot as there's nothing much you could
do with the information.

Anyway, cheers, and happy spec inspecting.

-Peter

--
Peter Seibel
pe...@javamonkey.com

Edi Weitz

unread,
Dec 28, 2002, 3:36:03 AM12/28/02
to
Pascal Bourguignon <p...@informatimago.com> writes:

> Edi Weitz <e...@agharta.de> writes:
>
> > Pascal Bourguignon <p...@informatimago.com> writes:
> >
> > > In HyperSpec, there are a lot of unresolved issues. 366 to be
> > > exact. So I find it amazing that they've not been working for
> > > ten years on resolving them.
> > > http://www.lispworks.com/reference/HyperSpec/Issues/I_Alpha.htm
> >
> > And I find it amazing that you haven't even understood the
> > introduction to the CLHS but nevertheless don't hesitate to troll
> > so loudly here. The "unresolved" issues you're talking about were
> > solved by the standard, in fact, the "issues" were part of the
> > process:
> >
> > <http://www.lispworks.com/reference/HyperSpec/Front/X3J13Iss.htm>
>
> Ok. So they are resolved. But they are not illuminating.

It is not the task of an ANSI standard to be illuminating. If you need
to be illuminated (which is fair to ask for) buy an introductory
text. (Or get an candle... :)

> > > So they've just approved a document with 366 unresolved issues
> > > and _known_ problems. I'm just pointing to another problem that
> > > does not seem to be known yet.
> >
> > Thank you very much. Could you please go somewhere else and try to
> > help there?
>
> No.

So be it.

Edi.

Edi Weitz

unread,
Dec 28, 2002, 3:39:52 AM12/28/02
to
Pascal Bourguignon <p...@informatimago.com> writes:

> Right now, I'm scanning HyperSpec and trying to implement missing
> COMMON-LISP functions on emacs, to allow me to use COMMON-LISP
> programs both in clisp and in emacs.

Have you tried (require 'cl) in Emacs?

Edi.

Alain Picard

unread,
Dec 28, 2002, 3:44:39 AM12/28/02
to
Pascal Bourguignon <p...@informatimago.com> writes:

[Long confused rant about constantp and a hypothethical
set-immutable snipped]

> [18]> (setq a (make-array 2 :initial-contents '(:toto 12)))
> #(:TOTO 12)
> [19]> (constantp a)
> T ;; this is not correct!
> [20]> (setf (aref a 0) :titi)
> :TITI
> [21]> a
> #(:TITI 12) ;; see! A is not constant !

Perhaps you failed to read the definition of
_constant_ _form_ in the spec.

Read what it _says_, not what you _think_ it says (or worse,
what you _wish_ it said) and you'll see there is no problem.

To paraphrase Bjarne Stroustrup: "If you want C++, you know
where to find it".

Erann Gat

unread,
Dec 28, 2002, 4:04:11 AM12/28/02
to
In article <87vg1em...@thalassa.informatimago.com>, Pascal Bourguignon
<p...@informatimago.com> wrote:

> So here are questions:

Here are answers.

> - what the language in CLHS means?
> Should (CONSTANTP (MAKE-ARRAY 2 :INITIAL-CONTENTS '(:A :B)))
> return T or NIL?

T

> Do you call the result of (MAKE-ARRAY ...) a constant?

No, but that's irrelevant. CONSTANTP doesn't tell you if its argument is
a constant, it tells you if its argument is a CONSTANT FORM, which is not
the same thing. A constant form is one which when passed as an argument
to EVAL always yields the same result. e.g:

(setf form1 '(make-array 5)) ; Form1 is a list
(setf form2 (make-array 5)) ; Form2 is an array

(constantp form1) --> nil
(constantp form2) --> t

Which implies:

(eq (eval form1) (eval form1)) --> nil
(eq (eval form2) (eval form2)) --> t

> How do you feel that CONSTANTP returns T for something you
> don't call a constant?

Perhaps a better name for this function would have been CONSTANT-FORM-P,
but this hardly seems worth quibbling over.

E.

Pascal Bourguignon

unread,
Dec 28, 2002, 4:55:23 AM12/28/02
to
Edi Weitz <e...@agharta.de> writes:

Of course, and I don't reimplement what's correctly implemented there
or in emacs.

--
__Pascal_Bourguignon__ http://www.informatimago.com/
----------------------------------------------------------------------

There is a fault in reality. Do not adjust your minds. -- Salman Rushdie

Rainer Joswig

unread,
Dec 28, 2002, 5:03:18 AM12/28/02
to
In article <87vg1em...@thalassa.informatimago.com>,
Pascal Bourguignon <p...@informatimago.com> wrote:

> - what the language in CLHS means?
> Should (CONSTANTP (MAKE-ARRAY 2 :INITIAL-CONTENTS '(:A :B)))
> return T or NIL?

According to CLHS it returns true. Just understand
that CONSTANTP returns T if it is a CONSTANT FORM . It
says nothing about immutable or not.

It just means something like: if you evaluate the thing you
always get the same thing as the result.

These are cases where CONSTANTP returns true:

- For any self-evaluating object (such as arrays) you always
get the same object as a result.
- For a constant symbol (such as pi) you always get the same
value (the value of pi).
- For every form (quote something) you always get this form
back (quote something).

So, CONSTANTP is not the same as immutablep (which does not exist
in Common Lisp). It means 'constant form under evaluation in
the indicated environment'.

"Same" usually means indistinguishable by the predicate EQL.

Pascal Bourguignon

unread,
Dec 28, 2002, 5:12:23 AM12/28/02
to

Alain Picard <apicard+die...@optushome.com.au> writes:

Ok, let's go at it once more:

constant form n. any form for which evaluation always yields the
same value, that neither affects nor is affected by the
environment in which it is evaluated (except that it is permitted
to refer to the names of constant variables defined in the
environment), and that neither affects nor is affected by the
state of any object except those objects that are otherwise
inaccessible parts of objects created by the form itself. ``A car
form in which the argument is a quote form is a constant form.''


So, constant form is a form.

Is (make-array 2 :initial-contents (list a b)) a form?

form n. 1. any object meant to be evaluated. 2. a symbol, a
compound form, or a self-evaluating object. 3. (for an operator,
as in ``<<operator>> form'') a compound form having that operator
as its first element. ``A quote form is a constant form.''

Well (make-array 2 :initial-contents (list a b) is a list meant to be
evaluated, so I'd say it's a form.

A constant form is a form which evaluation always yields the same value.
Ok, let's try that:

[3]> (setq a 1 b 2)
2
[4]> (eq (make-array 2 :initial-contents (list a b))
[4]> (make-array 2 :initial-contents (list a b)))
NIL

Oh oh! It seems that that form (make-array 2 :initial-contents (list
a b)) does not always return the same thing. But may be we have _two_
different form here, I've not said to the reader to use the
same. Let's try:


[11]> (defmacro double-eval (form) (list 'eq form form))
DOUBLE-EVAL
[12]> (setq *print-circle* t)
T
[13]> (macroexpand (quote
(double-eval (make-array 2 :initial-contents (list a b)))
))
(EQ #1=(MAKE-ARRAY 2 :INITIAL-CONTENTS (LIST A B)) #1#) ;
T
[14]> (double-eval (make-array 2 :initial-contents (list a b)))
NIL

Still not returning twice the same thing.


I could stop here saying that (MAKE-ARRAY 2 :INITIAL-CONTENTS (LIST A
B)) is not a constant form and that (CONSTANTP (MAKE-ARRAY 2
:INITIAL-CONTENTS (LIST A B))) should not return T, that clisp is
buggy (only that I can't say that because the COMMON-LISP standard
seems to say incoherently that it should return T.


Does (MAKE-ARRAY 2 :INITIAL-CONTENTS (LIST A B)) either affects or is


affected by the environment in which it is evaluated (except that it
is permitted to refer to the names of constant variables defined in

the environment)?

Indeed it is affected by the environment as can be seen with:

[15]> (setq a 1 b 2)
2
[16]> (make-array 2 :initial-contents (list a b))
#(1 2)
[17]> (setq a :a b :b)
:B
[18]> (make-array 2 :initial-contents (list a b))
#(:A :B)
[19]>

which shows that in addition to returning objects that are not EQ,
that same form can return objects that are even not EQUAL!


I could give an example of a form that neither fullfill the last
condition "and that neither affects nor is affected by the state of


any object except those objects that are otherwise inaccessible parts

of objects created by the form itself" for which CONSTANTP still
returns T, but it should be clear by now that there is a problem with
the specification of this function.


--
__Pascal_Bourguignon__ http://www.informatimago.com/
----------------------------------------------------------------------

There is a fault in reality. Do not adjust your minds. -- Salman Rushdie

Pascal Bourguignon

unread,
Dec 28, 2002, 5:36:57 AM12/28/02
to
g...@jpl.nasa.gov (Erann Gat) writes:

> In article <87vg1em...@thalassa.informatimago.com>, Pascal Bourguignon
> <p...@informatimago.com> wrote:
>
> > So here are questions:
>
> Here are answers.
>
> > - what the language in CLHS means?
> > Should (CONSTANTP (MAKE-ARRAY 2 :INITIAL-CONTENTS '(:A :B)))
> > return T or NIL?
>
> T
>
> > Do you call the result of (MAKE-ARRAY ...) a constant?
>
> No, but that's irrelevant. CONSTANTP doesn't tell you if its argument is
> a constant, it tells you if its argument is a CONSTANT FORM, which is not
> the same thing. A constant form is one which when passed as an argument
> to EVAL always yields the same result. e.g:
>
> (setf form1 '(make-array 5)) ; Form1 is a list
> (setf form2 (make-array 5)) ; Form2 is an array
>
> (constantp form1) --> nil
> (constantp form2) --> t
>
> Which implies:
>
> (eq (eval form1) (eval form1)) --> nil
> (eq (eval form2) (eval form2)) --> t

Ok, this starts to make sense. I can see that:

(eq (eval form2) (progn (setf (aref form2 0) :a) (eval form2))) --> t

which is coherent too.


So in my previous post, where I'm wrong with (constantp (make-array 2
:initial-contents (list a b))) is that the stuff that's meant to be
evaluated is not (make-array 2 :initial-contents (list a b)) but its
result, the array. I've let the evaluator play a trick on me there.
And indeed, even if that array is modified, when it's evaluated, as a
self evaluating form, it returns always itself (even if in a different
state).

In (eq (eval form2) (progn (setf (aref form2 0) :a) (eval form2))) eq
gets as its first argument the array in form2 : #1= when its value is
#(nil nil nil nil nil), and gets as its second argument the _same_
array in form2 #1#, when it's value has changed to #(:a nil nil nil
nil). Ok.


> > How do you feel that CONSTANTP returns T for something you
> > don't call a constant?
>
> Perhaps a better name for this function would have been CONSTANT-FORM-P,
> but this hardly seems worth quibbling over.
>
> E.

It's clear now. Thank you very much.


--
__Pascal_Bourguignon__ http://www.informatimago.com/
----------------------------------------------------------------------

There is a fault in reality. Do not adjust your minds. -- Salman Rushdie

Geoffrey Summerhayes

unread,
Dec 28, 2002, 5:53:15 AM12/28/02
to

"Pascal Bourguignon" <p...@informatimago.com> wrote in message news:87d6nmm...@thalassa.informatimago.com...

>
>
> A constant form is a form which evaluation always yields the same value.
> Ok, let's try that:
>
> [3]> (setq a 1 b 2)
> 2
> [4]> (eq (make-array 2 :initial-contents (list a b))
> [4]> (make-array 2 :initial-contents (list a b)))
> NIL
>
> Oh oh! It seems that that form (make-array 2 :initial-contents (list
> a b)) does not always return the same thing. But may be we have _two_
> different form here, I've not said to the reader to use the
> same.

The specification allows a Lisp implementation to do this:

>(constantp 3)
T
>(eq 3 3)
NIL

You can't use EQ to back your argument, it is not designed to compare
values.

--
Geoff


Kalle Olavi Niemitalo

unread,
Dec 28, 2002, 6:22:03 AM12/28/02
to
Pascal Bourguignon <p...@informatimago.com> writes:

> I could stop here saying that (MAKE-ARRAY 2 :INITIAL-CONTENTS (LIST A
> B)) is not a constant form and that (CONSTANTP (MAKE-ARRAY 2
> :INITIAL-CONTENTS (LIST A B))) should not return T

You are testing the wrong form.

(constantp '(make-array 2 :initial-contents (list a b)))
;; => NIL

Peter Seibel

unread,
Dec 28, 2002, 8:01:33 AM12/28/02
to
Pascal Bourguignon <p...@informatimago.com> writes:

But unless you quote it, you're not passing the form:

(make-array 2 :initial-contents (list a b)

to CONSTANTP. You're passing the result of evaluating that form.

> A constant form is a form which evaluation always yields the same
> value. Ok, let's try that:
>
> [3]> (setq a 1 b 2)
> 2
> [4]> (eq (make-array 2 :initial-contents (list a b))
> [4]> (make-array 2 :initial-contents (list a b)))
> NIL
>
> Oh oh! It seems that that form (make-array 2 :initial-contents (list
> a b)) does not always return the same thing. But may be we have
> _two_ different form here, I've not said to the reader to use the
> same.

Actually it's simpler than that: as you've demonstrated above, the
form "(make-array 2 :inital-contents (list a b))" doesn't always
evaluate to the same thing. From that and the definiton of CONSTANTP
we can infer that it should NOT be considered a constant form, i.e.

(constantp '(make-array 2 :initial-contents (list a b))) => NIL

(Note the single quote.) And indeed, in both CLISP and ACL we get the
expected result. Here's a transcript from ACL:

CL-USER(8): (defvar *a* 1)
*A*
CL-USER(11): (defvar *b* 2)
*B*
CL-USER(12): (constantp '(make-array 2 :initial-contents (list *a* *b*)))
NIL

If you evaluate your MAKE-ARRAY form (as happen automatically when you
type a CONSTANTP form to the toplevel REPL) you get an array which
*is* a constant form as the continuation of the transcript shows:

CL-USER(13): (constantp (make-array 2 :initial-contents (list *a* *b*)))
T
CL-USER(14): (make-array 2 :initial-contents (list *a* *b*))
#(1 2)
CL-USER(15): (constantp *)
T

Here's a macro that shows what's going on for any form:

(defmacro discuss-constantp (form)
(let* ((form-constant (constantp form))
(evaled (eval form))
(eval-constant (constantp evaled)))
`(progn
(format t
"~%~%Form \"~S\" ~:[IS NOT~;IS~] constantp. " ',form
,form-constant)
(format t
"~&It evaluates to \"~S\" which ~:[IS NOT~;IS~] a constantp form.~&~%"
',evaled
,eval-constant))))


Here are some examples (run in ACL 6.2, FWIW):

FOO(214): (discuss-constantp 1)

Form "1" IS constantp.
It evaluates to "1" which IS a constantp form.

NIL
FOO(216): (discuss-constantp #\a)

Form "#\a" IS constantp.
It evaluates to "#\a" which IS a constantp form.

NIL
FOO(217): (discuss-constantp (char "abc" 0))

Form "(CHAR "abc" 0)" IS NOT constantp.
It evaluates to "#\a" which IS a constantp form.

NIL
FOO(218): (discuss-constantp (list 1 2 3))

Form "(LIST 1 2 3)" IS NOT constantp.
It evaluates to "(1 2 3)" which IS NOT a constantp form.

NIL
FOO(219): (discuss-constantp #(1 2 3))

Form "#(1 2 3)" IS constantp.
It evaluates to "#(1 2 3)" which IS a constantp form.

NIL
FOO(220): (discuss-constantp (make-array 3 :initial-contents (list 1 2 3)))

Form "(MAKE-ARRAY 3 :INITIAL-CONTENTS (LIST 1 2 3))" IS NOT constantp.
It evaluates to "#(1 2 3)" which IS a constantp form.

NIL

> Let's try:
>
> [11]> (defmacro double-eval (form) (list 'eq form form))
> DOUBLE-EVAL
> [12]> (setq *print-circle* t)
> T
> [13]> (macroexpand (quote
> (double-eval (make-array 2 :initial-contents (list a b)))
> ))
> (EQ #1=(MAKE-ARRAY 2 :INITIAL-CONTENTS (LIST A B)) #1#) ;
> T
> [14]> (double-eval (make-array 2 :initial-contents (list a b)))
> NIL
>
> Still not returning twice the same thing.

Right. Because the reader reads:

(double-eval (make-array 2 :initial-contents (list a b)))

and expands it to:

(eq (make-array 2 :initial-contents (list a b)

(make-array 2 :initial-contents (list a b))))

If you look at that code as data then you notice (as you did with
(setq *print-circle* t)) that structurally the expression is using the
same data twice. But that has no effect on what happens next. To wit,
the whole expression is evaluated starting with the arguments from
left ...

(eq #(1 2) (make-array 2 :initial-contents (list a b))))

... to right ...

(eq #(1 2) #(1 2))

and then the application of the function bound to the symbol EQ to
those two values (which are different objects since each evaluation of
make-array returns a fresh object). And EQ tells us, ta da, that they
are in fact different objects.

> I could stop here saying that (MAKE-ARRAY 2 :INITIAL-CONTENTS (LIST A
> B)) is not a constant form and that (CONSTANTP (MAKE-ARRAY 2
> :INITIAL-CONTENTS (LIST A B))) should not return T, that clisp is
> buggy (only that I can't say that because the COMMON-LISP standard
> seems to say incoherently that it should return T.

You are correct that it's not a constant form. I believe it's
incorrect to say that CLISP says it is as you need to either quote the
form you pass to CONSTANTP or call CONSTANTP from within a macro in
order to run it on the unevaluated form. And I also don't see where
the CL standard says that a MAKE-ARRAY form is a constant form. (It
does say that arrays are constant forms. Arrays and MAKE-ARRAY
expressions are not the same thing.)

> Does (MAKE-ARRAY 2 :INITIAL-CONTENTS (LIST A B)) either affects or is
> affected by the environment in which it is evaluated (except that it
> is permitted to refer to the names of constant variables defined in
> the environment)?
>
> Indeed it is affected by the environment as can be seen with:

And indeed, as discussed above, the MAKE-ARRAY form is *not*
constantp. But after it's evaluated the thing it evaluates to *is*
constantp.

> [15]> (setq a 1 b 2)
> 2
> [16]> (make-array 2 :initial-contents (list a b))
> #(1 2)
> [17]> (setq a :a b :b)
> :B
> [18]> (make-array 2 :initial-contents (list a b))
> #(:A :B)
> [19]>
>
> which shows that in addition to returning objects that are not EQ,
> that same form can return objects that are even not EQUAL!

As it's documented to do. By way of contrast, consider that the array
itself (once it's been created) isn't affected by the environment:

FOO(259): (setq a 1 b 2)
2
FOO(262): (setq *array* (make-array 2 :initial-contents (list a b)))
#(1 2)
FOO(269): (setq a 3 b 4)
4
FOO(272): *array*
#(1 2)
FOO(273): (constantp *array*)
T

> I could give an example of a form that neither fullfill the last
> condition "and that neither affects nor is affected by the state of
> any object except those objects that are otherwise inaccessible
> parts of objects created by the form itself" for which CONSTANTP
> still returns T, but it should be clear by now that there is a
> problem with the specification of this function.

I don't think so.

Pascal Bourguignon

unread,
Dec 28, 2002, 9:55:48 AM12/28/02
to

Yes, I got confused and ignored the evaluation of the argument of
constantp that takes place. Now I understand.

Thank you.

Pascal Bourguignon

unread,
Dec 28, 2002, 10:11:57 AM12/28/02
to
Peter Seibel <pe...@javamonkey.com> writes:

> Pascal Bourguignon <p...@informatimago.com> writes:
> [...]


> > Well (make-array 2 :initial-contents (list a b) is a list meant to be
> > evaluated, so I'd say it's a form.
>
> But unless you quote it, you're not passing the form:
>
> (make-array 2 :initial-contents (list a b)
>
> to CONSTANTP. You're passing the result of evaluating that form.

> [...]

Yes that was the crux of my misunderstanding. For whatever reason, I
overlooked that the evaluator eval'ed the argument to constantp. (I
guess I've been side tracked by the problematic of immutability as in
this non conforming function fa:

[55]> (defun fa () (let (a) (setf (aref (setq a #(nil nil)) 0) :a) a))
FA
[56]> (symbol-function 'fa)
#<CLOSURE FA NIL (DECLARE (SYSTEM::IN-DEFUN FA))
(BLOCK FA (LET (A) (SETF (AREF (SETQ A #(NIL NIL)) 0) :A) A))>
[57]> (fa)
#(:A NIL)
[58]> (symbol-function 'fa)
#<CLOSURE FA NIL (DECLARE (SYSTEM::IN-DEFUN FA))
(BLOCK FA (LET (A) (SETF (AREF (SETQ A #(:A NIL)) 0) :A) A))>
)


Now I understand constantp, and everything reverts to normality.

Thank you for your help.

Rahul Jain

unread,
Dec 28, 2002, 11:54:54 AM12/28/02
to
Erik Naggum <er...@naggum.no> writes:

> Now that you have demonstrated that you believe that knowledge can
> be acquired without effort, how do you write programs? With a tap
> of your magic wand, the computer just does what you want, right?

I have this magic wand called `defmacro'. Unfortunately, its use
requires much practice and strange, sometimes complex incantations
involving backquotes and commas... :)

--
Rahul Jain

Paolo Amoroso

unread,
Dec 28, 2002, 12:42:33 PM12/28/02
to
On Fri, 27 Dec 2002 23:37:50 GMT, Barry Margolin <bar...@genuity.net>
wrote:

> Has the committee had any meetings or taken any action in the past few
> years? If there are any plans to produce a revision by 2005, I'd think

[...]


> Note: I didn't say that the standard was moribund, I said the *committee*
> was. If it's not really dead, it's playing it well. Was the 5-year

Last October Corman Technologies announced its intention to become a
committee voting member:

http://groups.yahoo.com/group/cormanlisp/message/876


Paolo
--
EncyCMUCLopedia * Extensive collection of CMU Common Lisp documentation
http://www.paoloamoroso.it/ency/README

Steven M. Haflich

unread,
Dec 28, 2002, 4:21:21 PM12/28/02
to
[Sorry if this message is duplicated. One of my two news
servers has crashed, causing all kinds of odd behavior.]

Pascal Bourguignon wrote:

> Right now, I'm scanning HyperSpec and trying to implement missing
> COMMON-LISP functions on emacs, to allow me to use COMMON-LISP
> programs both in clisp and in emacs. While I will keep to write LISP
> code for emacs, I'd like to make it as COMMON-LISP as possible and
> have as little dependencies on emacs as possible.

The problem achieving CL compatibility in Emacs lisp is
not so much the missing functions. Rather, it is the
different (mostly missing) semantics. Emacs lisp lacks
lexical variables, lexical functions, and closures. It
is relatively easy to code a missing function, but it is
really awkward to emulate missing semantics. It is possible
in the sense that you could implement full Common Lisp in
Emacs lisp (or C or Basic) but that is a very different task
than merely filling out some missing functions to augment an
existing language.

Steven M. Haflich

unread,
Dec 28, 2002, 4:23:26 PM12/28/02
to
[Sorry if this message is duplicated. One of my two news
servers has crashed, causing all kinds of odd behavior.]

The gist of Erann's response is essentially correct, but since
there has been an underlying subtext in this thread concerning
accuracy and adequacy of standards, I want to correct two minor
points. I don't intend this as provocative, and especially not
as criticism of Erann.

Erann Gat wrote:

> (constantp form1) --> nil
> (constantp form2) --> t
>
> Which implies:
>
> (eq (eval form1) (eval form1)) --> nil
> (eq (eval form2) (eval form2)) --> t

First, the appropriate predicate conceerning constantp is eql,
not eq. The definition of constantp refers to the glossary
term "constant form", which in turn refers to the glossary
term "same", which see. As an example, remember that two
identical numbers may be eql but not eq.

Second, if form1 is not constantp, the conclusion that

> (eq (eval form1) (eval form1)) --> nil

is unwarranted. As one counter example consider the form
(random 10), where the above test would presumably return
true about one time in ten. As another counter example,
consider the form (1+ pi). The result is probably constant
(assuming floating arithmetic is reproducible on the
particular system) but the implementation might not be able
to infer this, and there is no requirement that it do so.

Pascal Bourguignon

unread,
Dec 29, 2002, 3:35:31 AM12/29/02
to

Yes, I realize that.

But since the symbols both in elisp and in COMMON-LISP as are case
sensitive, and that elisp has all its symbols in low-case, and
COMMON-LISP has all its symbols in up-case, it should be possible to
implement both semantics in these different name spaces, while
allowing cross calling.

--
__Pascal_Bourguignon__ http://www.informatimago.com/
----------------------------------------------------------------------

There is a fault in reality. Do not adjust your minds. -- Salman Rushdie

J.L. Perez-de-la-Cruz

unread,
Jan 2, 2003, 6:56:07 AM1/2/03
to

Edi Weitz wrote:

> Pascal Bourguignon <p...@informatimago.com> writes:
> > Ok. So they are resolved. But they are not illuminating.

> It is not the task of an ANSI standard to be illuminating. If you need
> to be illuminated (which is fair to ask for) buy an introductory
> text. (Or get an candle... :)
>

Perhaps the right word in this context would be "enlightened" or
"awakened" and the correct technique in the Lisp world would be a
(verbal or ever better physical) koan:
http://www.tuxedo.org/~esr/jargon/html/Some-AI-Koans.html

0 new messages