From: Jacques Wainer
Subject: weird function behavior
Date: 
Message-ID: <hxwuu7vsof.fsf@vega.ic.unicamp.br>
Lispers

I student wrote the following code, whose behavior in clisp, below, I can't
explain. What can be happening here, or is this a bug in clisp?

(defun prob()
  (let ((x '(nil)))
    (push 1 (elt x 0))))


thanks

jacques



>clisp
  i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo
  I I I I I I I      8     8   8           8     8     o  8    8
  I  \ `+' /  I      8         8           8     8        8    8
   \  `-+-'  /       8         8           8      ooooo   8oooo
    `-__|__-'        8         8           8           8  8
        |            8     o   8           8     o     8  8
  ------+------       ooooo    8oooooo  ooo8ooo   ooooo   8

Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2001

[1]> (defun prob()
  (let ((x '(nil)))
    (push 1 (elt x 0))))
PROB
[2]> (prob)
(1)
[3]> (prob)
(1 1)                           ;;<--------------- problem
[4]> (prob)
(1 1 1)                         ;;<--------------- problem
[5]> (lisp-implementation-version )
"2.27 (released 2001-07-17) (built on tuiuiu.dcc.unicamp.br [143.106.7.90])"
[6]>
Bye.

From: Paul F. Dietz
Subject: Re: weird function behavior
Date: 
Message-ID: <3CE10B8D.398717DD@interaccess.com>
Jacques Wainer wrote:

> I student wrote the following code, whose behavior in clisp, below, I can't
> explain. What can be happening here, or is this a bug in clisp?
> 
> (defun prob()
>   (let ((x '(nil)))
>     (push 1 (elt x 0))))

This code destructively modifies a quoted constant.  The
consequences of this are undefined.

	Paul
From: Drew McDermott
Subject: Re: weird function behavior
Date: 
Message-ID: <3CE1207B.10405@yale.edu>
Jacques Wainer wrote:

I student wrote the following code, whose behavior in clisp, below, I 
can't explain. What can be happening here, or is this a bug in clisp?
> [1]> (defun prob()
>   (let ((x '(nil)))
>     (push 1 (elt x 0))))
> PROB
> [2]> (prob)
> (1)
> [3]> (prob)
> (1 1)                           ;;<--------------- problem
> [4]> (prob)
> (1 1 1)                         ;;<--------------- problem
> [5]> (lisp-implementation-version )
> "2.27 (released 2001-07-17) (built on tuiuiu.dcc.unicamp.br [143.106.7.90])"
> [6]>
> Bye.

It's the classic "mutating a constant" bug.  The compiler assumes that 
'(nil) is a constant, so it allocates storage for it at load time. 
Hence every time 'prob' is called the 'car' of the *same* list is changed.

Solution:

(defun prob()
    (let ((x (list nil)))
      (push 1 (elt x 0))))

This is guaranteed to create a new list every time, so 'prob' always 
returns (1).

Other cases to watch out for are things like using 'nconc' on a constant 
list:

(defun other-prob (y)
    (let ((x '(nil)))
       (setq x (nconc x y))
       x))

(other-prob '(a b)) => (nil a b)
(other-prob '(oops)) => (nil a b oops)

     -- Drew McDermott
From: Erik Naggum
Subject: Re: weird function behavior
Date: 
Message-ID: <3230400393774701@naggum.net>
* Jacques Wainer
| (defun prob()
|   (let ((x '(nil)))
|     (push 1 (elt x 0))))

  Where did you get the idea that you should use a quoted constant in your
  code to begin with?  I am actually seriously curious about this, because
  it is such an odd and counterintuitive thing to want to do that I am
  looking for some textbook author to blame or something.  If you thought
  it up on yourself, why did you think that a constant was a better choice
  than a freshly created list?  It is not the "don't modify a constant"
  that I wonder why people do not understand, it is their initial desire to
  use a constant in the first place that puzzles me.  What core concept do
  you have to have missed in order to believe that a constant is a suitable
  thing to specify when you know you are going to modify some part of it?

  A very weak conjecture on my part goes like this: People are used to
  programs that load fresh into a pristine environment where they can wreak
  havoc with constants and terminate wihout causing observable problems.
  There is no corrector to the abuse of these constants and because most
  programming languages make it easier to write constants than freshly
  created objects, the idea that using a constant could be an error does
  not arise consciously.  So when using a constant does not work, the
  _last_ thing they would think about is that the constant that is being
  modified actually _survives_ between what they are certain are fresh
  instantiations in a pristine environment.

  If my weak conjecture has merit, the solution to this problem is not to
  ask people to stop modifying constants, it is to teach people more about
  the execution models of computers, operating systems, and languages.
-- 
  In a fight against something, the fight has value, victory has none.
  In a fight for something, the fight is a loss, victory merely relief.

  70 percent of American adults do not understand the scientific process.
From: Will Hartung
Subject: Re: weird function behavior
Date: 
Message-ID: <3ce18d9f$1_3@news.teranews.com>
"Erik Naggum" <····@naggum.net> wrote in message
·····················@naggum.net...

>   A very weak conjecture on my part goes like this: People are used to
>   programs that load fresh into a pristine environment where they can
wreak
>   havoc with constants and terminate wihout causing observable problems.

This is very possible. Lisp Is Different than most other languages in this
regard.

>   There is no corrector to the abuse of these constants and because most
>   programming languages make it easier to write constants than freshly
>   created objects, the idea that using a constant could be an error does
>   not arise consciously.

"Notational Convenience" is also possible cause. Certainly '(a b c) is much
easier to type than (list 'a 'b 'c). Also, it wouldn't surprise me if people
considered the notation of '(a b c) to be very similar to "abc", where one
creates a list, and the other creates a string. People tend to have a lot
more trouble with constant lists and side-effects than with constant
strings.

Also, for example in Java, if you do 's = "abc"', since strings are
immutable, there's no chance that 's' will have any reuse problems. Someone
from that background could easily "assume" the Javas 'String s = "abc"' is
equivalent to (let ((s "abc"))). They'd be wrong, but they certainly look
similar.

Now clearly, they're guilty of bringing preconceptions from language X into
Lisp, but there's no stopping that.

>   So when using a constant does not work, the
>   _last_ thing they would think about is that the constant that is being
>   modified actually _survives_ between what they are certain are fresh
>   instantiations in a pristine environment.
>
>   If my weak conjecture has merit, the solution to this problem is not to
>   ask people to stop modifying constants, it is to teach people more about
>   the execution models of computers, operating systems, and languages.

The solution is to tell people about this, watch the information bounce
cleanly off of their skulls as if teflon coated and then refresh their
memory when they stumble upon it slowly eating their program alive, which
they most certainly will.

When the constant abuse manifests itself as a problem, it can be a bugger to
track down, but it's one of those "It will only bite you once" bugs that's
seems to always be taught the hard way, particularly when people are
self-taught rather than formally intructed. In a formal setting, this
behavior of the language might be brought to light by the instructor. Not
that the students will listen.

I was burned by this issue recently, and while obvious in hindsight, it
wasn't when it was happening.

Regards,

Will
From: Kenny Tilton
Subject: Re: weird function behavior
Date: 
Message-ID: <3CE19627.B8547ABC@nyc.rr.com>
Erik Naggum wrote:
> 
> * Jacques Wainer
> | (defun prob()
> |   (let ((x '(nil)))
> |     (push 1 (elt x 0))))
> 
>   Where did you get the idea that you should use a quoted constant in your
>   code to begin with?  I am actually seriously curious about this, because...

I bet it is Kent Pitman's fault <g> for pushing for '() vis nil when
establishing an intended binding to an empty list. I bet the bloke
remembered '() as '(nil). Simple goof.

Except now we have to explain why it's Ok to modify the constant '() but
no other constants. 

:)

-- 

 kenny tilton
 clinisys, inc
 ---------------------------------------------------------------
"Harvey has overcome not only time and space but any objections."
                                                        Elwood P. Dowd
From: Kent M Pitman
Subject: Re: weird function behavior
Date: 
Message-ID: <sfwg00ub9mv.fsf@shell01.TheWorld.com>
Kenny Tilton <·······@nyc.rr.com> writes:

> Erik Naggum wrote:
> > 
> > * Jacques Wainer
> > | (defun prob()
> > |   (let ((x '(nil)))
> > |     (push 1 (elt x 0))))
> >   
> >   Where did you get the idea that you should use a quoted constant
> >   in your code to begin with?  I am actually seriously curious
> >   about this, because...
> 
> I bet it is Kent Pitman's fault <g> for pushing for '() vis nil when
> establishing an intended binding to an empty list. I bet the bloke
> remembered '() as '(nil). Simple goof.
> 
> Except now we have to explain why it's Ok to modify the constant '() but
> no other constants. 

[I'll just ignore the issue of what's my fault or not, but...]

Where is '() modified?

Do you mean in 
 (let ((x '()))
   (push 1 x))

This is one reason I don't like thinking of SETQ (and by implication PUSH)
as a "modifier" operations.  They are not mutating data.  They are only 
changing program state.  Program state may at some meta-level be data, but
it is not immutable data at that level; it is data that has been freshly
allocated for the purpose of mutation.

Or maybe I'm misunderstanding your point.
From: Kenny Tilton
Subject: Re: weird function behavior
Date: 
Message-ID: <3CE1A4E5.B5C4A297@nyc.rr.com>
Kent M Pitman wrote:
> 
> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> > Erik Naggum wrote:
> > >
> > > * Jacques Wainer
> > > | (defun prob()
> > > |   (let ((x '(nil)))
> > > |     (push 1 (elt x 0))))
> > >
> > >   Where did you get the idea that you should use a quoted constant
> > >   in your code to begin with?  I am actually seriously curious
> > >   about this, because...
> >
> > I bet it is Kent Pitman's fault <g> for pushing for '() vis nil when
> > establishing an intended binding to an empty list. I bet the bloke
> > remembered '() as '(nil). Simple goof.
> >
> > Except now we have to explain why it's Ok to modify the constant '() but
> > no other constants.
> 
> [I'll just ignore the issue of what's my fault or not, but...]

Just kidding!

> 
> Where is '() modified?
> 

Nowhere, and I should have said "...use a quoted constant". That was
ironic, meant to be the reaction of a newbie. And newbies will def freak
over using the quoted constant '(nil) being a mortal sin, so use '()
dammit! hunh? that's still a quoted constant! 

otoh, i /do/ believe newbies need this deep stuff so they get past the
syntactic sugar and can "see" the cons cells (or not in the case of nil)
behind the syntax.

-- 

 kenny tilton
 clinisys, inc
 ---------------------------------------------------------------
"Harvey has overcome not only time and space but any objections."
                                                        Elwood P. Dowd
From: Coby Beck
Subject: Re: weird function behavior
Date: 
Message-ID: <ivjE8.72708$uE2.5687477@news2.calgary.shaw.ca>
Erik Naggum <····@naggum.net> wrote in message
·····················@naggum.net...
> * Jacques Wainer
> | (defun prob()
> |   (let ((x '(nil)))
> |     (push 1 (elt x 0))))
>
>   Where did you get the idea that you should use a quoted constant in your
>   code to begin with?  I am actually seriously curious about this, because
>   it is such an odd and counterintuitive thing to want

Intuition is a personal thing, so while it may be counter intuitive to you,
it does not seem to be so to alot of others.  I can include myself in that
boat as In The Beginning I never thought twice about doing that when making
lists of symbols and such.

I recall code from people like Winston and Horn that defined parameters this
way and then modified it in programs, stuff we studied in AI courses.  I
know that is outdated, but I didn't when I learned it.

It is also easy to take your top level habits into code files and who
doesn't type (setf foo '(a b c d)) at top level?  Most people do not read
the fine print before starting to get things done.  This may not be the
wisest approach but it certainly lends itself to getting a job done.
(Granted it is often not the best job, but that is what experience is all
about, isn't it?)

>   If you thought
>   it up on yourself, why did you think that a constant was a better choice
>   than a freshly created list?  It is not the "don't modify a constant"
>   that I wonder why people do not understand, it is their initial desire
to
>   use a constant in the first place that puzzles me.

What you don't consider is that people might not realize it *is* a constant.
There is certainly no obvious visual clue, like defconstant.  When I learned
lisp, QUOTE was just a way to get an unevaluated list, a way to stop the
annoying "undefined function A called with args (B C)" messages.

>   What core concept do
>   you have to have missed in order to believe that a constant is a
suitable
>   thing to specify when you know you are going to modify some part of it?

This question is not the right one, see above.

It is an obvious FAQ but I don't think it is a stupid mistake at all.  Not
enough Lisp teachers are former lisp programmers, that's all.

--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Brad Miller
Subject: Re: weird function behavior (or just weird CL spec)
Date: 
Message-ID: <abujk4$4vv$1@newshost.mot.com>
I'm with Coby. '(a b c) denotes a list consisting of three atoms, but not
necessarily a particular list. It is not a proper name of a list that is
subject to change, but rather an attributive identifier, specifying a list
that has exactly the nature that it is EQUAL to '(a b c). Such
specifications for a list should be used as a specification.

A more reasonable lisp interpreter or compiler would put this list in
read-only space, and then copy it on write... and anytime it encountered a
quoted constant in code it would take it as a specification, not as a
reference. (Or attributive reference instead of a referential reference in
the Donnelan Distinction).

"Coby Beck" <·····@mercury.bc.ca> wrote in message
····························@news2.calgary.shaw.ca...
>
> Erik Naggum <····@naggum.net> wrote in message
> ·····················@naggum.net...
> > * Jacques Wainer
> > | (defun prob()
> > |   (let ((x '(nil)))
> > |     (push 1 (elt x 0))))
> >
> >   Where did you get the idea that you should use a quoted constant in
your
> >   code to begin with?  I am actually seriously curious about this,
because
> >   it is such an odd and counterintuitive thing to want
>
> Intuition is a personal thing, so while it may be counter intuitive to
you,
> it does not seem to be so to alot of others.  I can include myself in that
> boat as In The Beginning I never thought twice about doing that when
making
> lists of symbols and such.
>
> I recall code from people like Winston and Horn that defined parameters
this
> way and then modified it in programs, stuff we studied in AI courses.  I
> know that is outdated, but I didn't when I learned it.
>
> It is also easy to take your top level habits into code files and who
> doesn't type (setf foo '(a b c d)) at top level?  Most people do not read
> the fine print before starting to get things done.  This may not be the
> wisest approach but it certainly lends itself to getting a job done.
> (Granted it is often not the best job, but that is what experience is all
> about, isn't it?)
>
> >   If you thought
> >   it up on yourself, why did you think that a constant was a better
choice
> >   than a freshly created list?  It is not the "don't modify a constant"
> >   that I wonder why people do not understand, it is their initial desire
> to
> >   use a constant in the first place that puzzles me.
>
> What you don't consider is that people might not realize it *is* a
constant.
> There is certainly no obvious visual clue, like defconstant.  When I
learned
> lisp, QUOTE was just a way to get an unevaluated list, a way to stop the
> annoying "undefined function A called with args (B C)" messages.
>
> >   What core concept do
> >   you have to have missed in order to believe that a constant is a
> suitable
> >   thing to specify when you know you are going to modify some part of
it?
>
> This question is not the right one, see above.
>
> It is an obvious FAQ but I don't think it is a stupid mistake at all.  Not
> enough Lisp teachers are former lisp programmers, that's all.
>
> --
> Coby Beck
> (remove #\Space "coby 101 @ bigpond . com")
>
>
From: Kaz Kylheku
Subject: Re: weird function behavior (or just weird CL spec)
Date: 
Message-ID: <slrnaelfl3.skc.kaz@localhost.localdomain>
On Wed, 15 May 2002 14:23:10 -0700, Brad Miller
<·················@NOSPAMmotorola.com> wrote:
>I'm with Coby. '(a b c) denotes a list consisting of three atoms, but not
>necessarily a particular list. It is not a proper name of a list that is
>subject to change, but rather an attributive identifier, specifying a list
>that has exactly the nature that it is EQUAL to '(a b c). Such
>specifications for a list should be used as a specification.
>
>A more reasonable lisp interpreter or compiler would put this list in
>read-only space, and then copy it on write... and anytime it encountered a

(defun frob-it (cons)
 (setf (car cons) 42))

(frob-it (cdr '(a b c)))

How does the compiler know, when translating frob-it, that the setf
modifies a constant list which must be subject to copy-on write?

Any time a cons cell is modified anywhere in the program, the implementation
will have to suspect that it may be the element of a read-only list,
or, more generally, the element of a list which has some read-write cons cells,
and a tail of one or more read-only cells.

Maybe every such modification can test the address of the object to note that
it is in read-only storage? 

But then you are still looking at a semantics change. If setf returns a new
object, and doesn't modify the specified place, it is not behaving as
specified. Programs can now break, because they are not prepared to deal with
this.

No, the only good thing to do with the extra information would be to
signal an error, that a read-only cons is being modified.

Only if you deal with lists as whole units is it feasible to do the
copy-on-write approach. This is, of course, what Lisp programmers do
manually:  when they want to encode a literal list into a program, but also
have it modifiable, they perhaps write their intent like this:

  (copy-list '(a b c))

>quoted constant in code it would take it as a specification, not as a
>reference.

The problem is that lists obtained from quoted list expressions can be
communicated throughout the program, into contexts where their origin is not
apparent. Which means that cells then have to have a read-only attribute as
part of their latent type information. 

If modification of literals were permitted by the language, then compilers
would inevitably have to make pessimistic assumptions. Many occurences of
literals which are never modified would have to nevertheless generate new
objects each time they are evaluated, simply because the compiler couldn't
prove that they are never modified.

For instance, any time a quoted list is passed to some function, it would have
to be suspected that the function can be dynamically replaced with one that
modifies the list, even if at the time of compilation the function can be
analyzed to show that it does not.

-- 
Meta-CVS: solid version control tool with directory structure versioning. 
http://users.footprints.net/~kaz/mcvs.html  http://freshmeat.net/projects/mcvs
From: Robert Maas
Subject: Re: weird function behavior (or just weird CL spec)
Date: 
Message-ID: <ef5aa6c5.0205221026.2fa154f2@posting.google.com>
···@localhost.localdomain (Kaz Kylheku) wrote in message news:<··················@localhost.localdomain>...
> (defun frob-it (cons)
>  (setf (car cons) 42))
> (frob-it (cdr '(a b c)))

That combo is contradictory. The constant expression can't be changed,
yet the function-call invokes a change to it. "IT IS AN ERROR" to attempt
to do such things. Any really good implementation should signal an
error sometime when executing that function call, after first warning
of the problem when incrementally compiling the function call, just as
CMUCL does when compiling (go nonexistantlabel) then later if that expression
actually gets executed. (Hence  (if x (go foo)) generates only the warning
not the error if x happens to be false when the form is executed.)
A really bad implementation would be permitted to erase your hard disk
and set fire to your computer. A lazy implementation would probably just
coredump at some point. An implementation that is lazy about this particular
rare problem but careful in general would signal an error such as illegal
memory reference, or just allow all the code that sees that now-modified
constant to break in strange ways, such as signalling an error that
the impossible has happened, it fell out the bottom of an ecase without
executing the regular error exprssion it's supposed to always do when
that happens, or signalling that the value of NIL is not null, etc...
Actually a very likely error somewhere in the code is an error that
b doesn't have a value cell (because at compile time it could be proven
that the CADR of that original 3-list would always be b, so some error
message somewhere was condensed with the name 'b' frozen into the message text,
so when it was found that 42 didn't have a value cell it'd print the
already-frozen message about b instead of making a new message about 42).
Why does it say b doesn't have a value cell, instead of saying b isn't
a symbol? Because somebody generalized the idea of value cells to include
things other than symbols, and encapulated this functionality into stuff
like (defun has-value-cell-p (object) ...) and
(defmacro safe-setf (place newval) ...) which checks if the place is
something with some kind of extended value cell before attempting
setf on it and issues that message, so the expression
(safe-setf (symbol-value (cadr '(a b c))) x) if compiled with inline somesuch
might expand to include such a message as
(error "The place ~S doesn't have a value cell" (cadr '(a b c)))
which gets optimized to
(error "The place ~S doesn't have a value cell" 'b)
which then gets optimized further to
(error "The place b doesn't have a value cell")
voila! Look at all the trouble you get into with an optimizing compiler
if you lie to it about whether something is constant or not!

> Maybe every such modification can test the address of the object to note that
> it is in read-only storage?

Yes. Note that the read-only bit for that page of memory gets toggled
to writeable (during a critical section) briefly whenever new constants
are appended to the end of that page, until it is full and then it remains
read-only forever after (until you QUIT your coreimage).

> No, the only good thing to do with the extra information would be to
> signal an error, that a read-only cons is being modified.

I agree.

> Only if you deal with lists as whole units is it feasible to do the
> copy-on-write approach. This is, of course, what Lisp programmers do
> manually:  when they want to encode a literal list into a program, but also
> have it modifiable, they perhaps write their intent like this:
>   (copy-list '(a b c))

I agree. Tell the truth to your compiler at all times!! If you want each
instance of this in the code to be a different copy, write that copy-list
everywhere it occurs. If you want a single master list that everyone in
the whole program (or package) can modify to pass side effects back and
forth, put the copy-list in a defvar. LISP has so many ways of doing
*almost* the same thing, you as a programmer must make sure you say
exactly what you mean, which actually is possible in LISP unlike many
other languages!!

> The problem is that lists obtained from quoted list expressions can be
> communicated throughout the program, into contexts where their origin is not
> apparent. Which means that cells then have to have a read-only attribute as
> part of their latent type information.

You mean the fact that something is constant is 'latent'?? Fine, we all
agree it should be written onto a read-only page.

> If modification of literals were permitted by the language, then compilers
> would inevitably have to make pessimistic assumptions. Many occurences of
> literals which are never modified would have to nevertheless generate new
> objects each time they are evaluated, simply because the compiler couldn't
> prove that they are never modified.

Yes! That's what is so good about modern compilers, avoiding that overhead
where possible, and the pain if the programmer tries to lie to the compiler,
rather like ordering a trained dog to stick its nose in an electrical outlet.
From: Robert Maas
Subject: Re: weird function behavior (or just weird CL spec)
Date: 
Message-ID: <ef5aa6c5.0205220830.3baf549b@posting.google.com>
"Brad Miller" <·················@NOSPAMmotorola.com> wrote in message news:<············@newshost.mot.com>...
> I'm with Coby. '(a b c) denotes a list consisting of three atoms, but not
> necessarily a particular list. It is not a proper name of a list that is
> subject to change, but rather an attributive identifier, specifying a list
> that has exactly the nature that it is EQUAL to '(a b c). Such
> specifications for a list should be used as a specification.

I agree completely. Accordingly there are only two places such a syntax
should be allowed:
- In a defconstant, as the value.
- Directly in code where it can be proven the value will never be modified.
"It is an error", or should be, to use it anywhere else in an implementation
that doesn't have runtime protection against modifying the data.

More of my opinion: If it's used more than once in the same package or
application with the same semantics, it should be in a defconstant.
If it's used just once, it's your choice defconstant or inline.

> A more reasonable lisp interpreter or compiler would put this list in
> read-only space, and then copy it on write... and anytime it encountered a
> quoted constant in code it would take it as a specification, not as a
> reference. (Or attributive reference instead of a referential reference in
> the Donnelan Distinction).

I basically agree, although your mileage of details may vary...
From: Nils Goesche
Subject: Re: weird function behavior (or just weird CL spec)
Date: 
Message-ID: <lk3cwk6lg2.fsf@pc022.bln.elmeg.de>
···@netmagic.net (Robert Maas) writes:

> "Brad Miller" <·················@NOSPAMmotorola.com> wrote in message news:<············@newshost.mot.com>...
> > I'm with Coby. '(a b c) denotes a list consisting of three atoms, but not
> > necessarily a particular list. It is not a proper name of a list that is
> > subject to change, but rather an attributive identifier, specifying a list
> > that has exactly the nature that it is EQUAL to '(a b c). Such
> > specifications for a list should be used as a specification.
> 
> I agree completely. Accordingly there are only two places such a syntax
> should be allowed:
> - In a defconstant, as the value.

What would that help?  The consequences of

(defconstant +a+ 17)

(incf +a+)

are undefined, too.

> - Directly in code where it can be proven the value will never be
>   modified.

Proven by whom?  It is already the case that literals should only be
used if it is absolutely certain that they will never be modified.  It
is the programmer who has to prove this, to himself or to the reader
in a comment, or through specification of an access protocol.  That
should be good enough.  Compilers that reject code of mine because
/they/ can't prove its correctness make me sick.  (You only mentioned
list literals, BTW.  How about string literals?)

One might indeed discuss if is a good idea to place such literals into
read-only memory pages and signal an error on attempts to modify them,
whenever the OS makes that possible and convenient, which compilers
are already free to do, I think.  But if you start putting gratuitous
restrictions into the language just because some newbies might
otherwise write incorrect programs, there is nowhere to stop in Lisp:
Lisp is /full/ with assumptions that the programmer knows best what he
is doing, and if you want to get rid of those, you'll end up with a
completely different language.  If I want Java or *ML, I know where to
find them.

Regards,
-- 
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x42B32FC9
From: Coby Beck
Subject: Re: weird function behavior (or just weird CL spec)
Date: 
Message-ID: <LdPG8.30132$Ka.2287442@news2.calgary.shaw.ca>
Brad Miller <·················@NOSPAMmotorola.com> wrote in message
·················@newshost.mot.com...
> I'm with Coby. '(a b c) denotes a list consisting of three atoms, but not
> necessarily a particular list.

Hi, Brad.

Don't forget that what I was expressing in my reply to Erik you quoted below
is what I *used* to think, only by lazy assumption.  I was trying to show
how it is an easy mistake to make.  It is however, still a mistake!

Please refer to Kaz's very clear explanation in another message of why
things should not be the way you describe below.

--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")

[the remainder of this post is just quoted text]

> It is not a proper name of a list that is
> subject to change, but rather an attributive identifier, specifying a list
> that has exactly the nature that it is EQUAL to '(a b c). Such
> specifications for a list should be used as a specification.
>
> A more reasonable lisp interpreter or compiler would put this list in
> read-only space, and then copy it on write... and anytime it encountered a
> quoted constant in code it would take it as a specification, not as a
> reference. (Or attributive reference instead of a referential reference in
> the Donnelan Distinction).
>
> "Coby Beck" <·····@mercury.bc.ca> wrote in message
> ····························@news2.calgary.shaw.ca...
> >
> > Erik Naggum <····@naggum.net> wrote in message
> > ·····················@naggum.net...
> > > * Jacques Wainer
> > > | (defun prob()
> > > |   (let ((x '(nil)))
> > > |     (push 1 (elt x 0))))
> > >
> > >   Where did you get the idea that you should use a quoted constant in
> your
> > >   code to begin with?  I am actually seriously curious about this,
> because
> > >   it is such an odd and counterintuitive thing to want
> >
> > Intuition is a personal thing, so while it may be counter intuitive to
> you,
> > it does not seem to be so to alot of others.  I can include myself in
that
> > boat as In The Beginning I never thought twice about doing that when
> making
> > lists of symbols and such.
> >
> > I recall code from people like Winston and Horn that defined parameters
> this
> > way and then modified it in programs, stuff we studied in AI courses.  I
> > know that is outdated, but I didn't when I learned it.
> >
> > It is also easy to take your top level habits into code files and who
> > doesn't type (setf foo '(a b c d)) at top level?  Most people do not
read
> > the fine print before starting to get things done.  This may not be the
> > wisest approach but it certainly lends itself to getting a job done.
> > (Granted it is often not the best job, but that is what experience is
all
> > about, isn't it?)
> >
> > >   If you thought
> > >   it up on yourself, why did you think that a constant was a better
> choice
> > >   than a freshly created list?  It is not the "don't modify a
constant"
> > >   that I wonder why people do not understand, it is their initial
desire
> > to
> > >   use a constant in the first place that puzzles me.
> >
> > What you don't consider is that people might not realize it *is* a
> constant.
> > There is certainly no obvious visual clue, like defconstant.  When I
> learned
> > lisp, QUOTE was just a way to get an unevaluated list, a way to stop the
> > annoying "undefined function A called with args (B C)" messages.
> >
> > >   What core concept do
> > >   you have to have missed in order to believe that a constant is a
> > suitable
> > >   thing to specify when you know you are going to modify some part of
> it?
> >
> > This question is not the right one, see above.
> >
> > It is an obvious FAQ but I don't think it is a stupid mistake at all.
Not
> > enough Lisp teachers are former lisp programmers, that's all.
> >
> > --
> > Coby Beck
> > (remove #\Space "coby 101 @ bigpond . com")
> >
> >
>
>
From: Jacques Wainer
Subject: Re: weird function behavior
Date: 
Message-ID: <hxbsbhtqc6.fsf@xingu.dcc.unicamp.br>
Erik Naggum <····@naggum.net> writes:

| * Jacques Wainer
| | (defun prob()
| |   (let ((x '(nil)))
| |     (push 1 (elt x 0))))
| 
|   Where did you get the idea that you should use a quoted constant in your
|   code to begin with?  I am actually seriously curious about this, because


no where there is any indication that '(nil) is a constant. The
fact that the complier/evaluator considers that a constant to me is
a bad design decision. In fact, I could accept that the compiler, with
optimization set to a high level, would implement '(nil) as a
constant but I would not expect the evaluator in clisp, to perform
such optimization.
Before this event, I thought '(nil) to be operationally equivalent to
(list nil), but just notationally more convenient. 


|   it is such an odd and counterintuitive thing to want to do that I am
|   looking for some textbook author to blame or something.  If you thought
|   it up on yourself, why did you think that a constant was a better choice
|   than a freshly created list?  It is not the "don't modify a constant"
|   that I wonder why people do not understand, it is their initial desire to
|   use a constant in the first place that puzzles me.  What core concept do
|   you have to have missed in order to believe that a constant is a suitable
|   thing to specify when you know you are going to modify some part of it?
 
answered above. 

| 
|   A very weak conjecture on my part goes like this: People are used to
|   programs that load fresh into a pristine environment where they can wreak
|   havoc with constants and terminate wihout causing observable problems.
|   There is no corrector to the abuse of these constants and because most
|   programming languages make it easier to write constants than freshly
|   created objects, the idea that using a constant could be an error does
|   not arise consciously.  So when using a constant does not work, the
|   _last_ thing they would think about is that the constant that is being
|   modified actually _survives_ between what they are certain are fresh
|   instantiations in a pristine environment.
| 
|   If my weak conjecture has merit, the solution to this problem is not to
|   ask people to stop modifying constants, it is to teach people more about
|   the execution models of computers, operating systems, and languages.
From: Coby Beck
Subject: Re: weird function behavior
Date: 
Message-ID: <o4vE8.77881$GG6.6799883@news3.calgary.shaw.ca>
Jacques Wainer <······@ic.unicamp.br> wrote in message
···················@xingu.dcc.unicamp.br...
> Erik Naggum <····@naggum.net> writes:
>
> | * Jacques Wainer
> | | (defun prob()
> | |   (let ((x '(nil)))
> | |     (push 1 (elt x 0))))
> |
> |   Where did you get the idea that you should use a quoted constant in
your
> |   code to begin with?  I am actually seriously curious about this,
because
>
>
> no where there is any indication that '(nil) is a constant. The
> fact that the complier/evaluator considers that a constant to me is
> a bad design decision. In fact, I could accept that the compiler, with
> optimization set to a high level, would implement '(nil) as a
> constant but I would not expect the evaluator in clisp, to perform
> such optimization.
> Before this event, I thought '(nil) to be operationally equivalent to
> (list nil), but just notationally more convenient.

As I said in another post, this was my initial misconception as well.  The
fact is though, you and I have no real excuse, it is clearly stated in the
hyperspec on the first screenful of documentation for QUOTE that we should
not modify these literal objects.  It is such a common mistake though, that
those of us who don't make it any more really should not get upset seeing
other's fall into that trap.  Thankfully, it is also the kind of bug that
bites so hard, either because of the frustration tracking it down or the
shock of finding out something you do so casually and so often is so wrong,
that it is not a mistake you are likely to repeat.

"A bad design decision" is an overly harsh statement.  At *worst* you can
say that it seems counterintuitive to you and (absent any background for the
decision) arbitrary.  But language is full of arbitrary features that only
make sense because we all agree on what they will mean.  I don't know the
reasoning that went into defining QUOTE this way but now that I understand
it, there is no problem and frankly no reason to be upset for it.

--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Geoff Summerhayes
Subject: Re: weird function behavior
Date: 
Message-ID: <NcvE8.78452$xS2.6379322@news1.calgary.shaw.ca>
"Jacques Wainer" <······@ic.unicamp.br> wrote in message
···················@xingu.dcc.unicamp.br...
>
> no where there is any indication that '(nil) is a constant. The
> fact that the complier/evaluator considers that a constant to me is
> a bad design decision. In fact, I could accept that the compiler, with
> optimization set to a high level, would implement '(nil) as a
> constant but I would not expect the evaluator in clisp, to perform
> such optimization.
> Before this event, I thought '(nil) to be operationally equivalent to
> (list nil), but just notationally more convenient.

Actually, '(nil) is expanded to (quote (nil)), and there is no
`optimization' involved. QUOTE prevents it's argument from being
evaluated and just returns it when called. Although possible, it
is rare to find a CL implementation that returns a new object
every time.

It is kind of cute hearing that there is no indication that '(nil)
is constant...the ' screams, "CONSTANT!!" to me just like a double
quoted string would in C/C++.

------
Geoff
From: Kent M Pitman
Subject: Re: weird function behavior
Date: 
Message-ID: <sfwlmalht2f.fsf@shell01.TheWorld.com>
"Geoff Summerhayes" <·············@hNoOtSmPaAiMl.com> writes:

> "Jacques Wainer" <······@ic.unicamp.br> wrote in message
> ···················@xingu.dcc.unicamp.br...
> >
> > no where there is any indication that '(nil) is a constant. The
> > fact that the complier/evaluator considers that a constant to me is
> > a bad design decision. In fact, I could accept that the compiler, with
> > optimization set to a high level, would implement '(nil) as a
> > constant but I would not expect the evaluator in clisp, to perform
> > such optimization.
> > Before this event, I thought '(nil) to be operationally equivalent to
> > (list nil), but just notationally more convenient.
> 
> Actually, '(nil) is expanded to (quote (nil)), and there is no
> `optimization' involved. QUOTE prevents it's argument from being
> evaluated and just returns it when called. Although possible, it
> is rare to find a CL implementation that returns a new object
> every time.
> 
> It is kind of cute hearing that there is no indication that '(nil)
> is constant...the ' screams, "CONSTANT!!" to me just like a double
> quoted string would in C/C++.


There are, incidentally, two issues at play here:

 - literal (self-evaluting) datum

 - modifiable datum

Literal data could have been designed to inhibit evaluation but still
allow modification. In that case, this function would behave as if it
had what Algol called "own variables".  That would have some practical
applications but would also invite still even more bugs.  We finally
came up with LOAD-TIME-VALUE as a perspicuous way of treating data that
was to be unchanging at runtime but yet still modifiable.
From: Frode Vatvedt Fjeld
Subject: Re: weird function behavior
Date: 
Message-ID: <2helgd1lyf.fsf@vserver.cs.uit.no>
Jacques Wainer <······@ic.unicamp.br> writes:

> Before this event, I thought '(nil) to be operationally equivalent
> to (list nil), but just notationally more convenient.

'(nil) is alternative notation for (quote (nil)), as '<x> in general
means (quote <x>). Quote returns a literal object, whereas list
constructs a list, and you should understand the difference.

-- 
Frode Vatvedt Fjeld
From: Nils Goesche
Subject: Re: weird function behavior
Date: 
Message-ID: <lksn4tcskt.fsf@pc022.bln.elmeg.de>
Jacques Wainer <······@ic.unicamp.br> writes:

> Erik Naggum <····@naggum.net> writes:
> 
> | * Jacques Wainer
> | | (defun prob()
> | |   (let ((x '(nil)))
> | |     (push 1 (elt x 0))))
> | 
> |   Where did you get the idea that you should use a quoted constant in your
> |   code to begin with?  I am actually seriously curious about this, because
> 
> no where there is any indication that '(nil) is a constant. The
> fact that the complier/evaluator considers that a constant to me is
> a bad design decision. In fact, I could accept that the compiler, with
> optimization set to a high level, would implement '(nil) as a
> constant but I would not expect the evaluator in clisp, to perform
> such optimization.
> Before this event, I thought '(nil) to be operationally equivalent to
> (list nil), but just notationally more convenient. 

Well, they are not, and in several ways:

CL-USER 24 > (defun foo ()
               '(nil))
FOO

CL-USER 25 > (defun bar ()
               (list nil))
BAR

CL-USER 26 > (eql (foo) (foo))
T

CL-USER 27 > (eql (bar) (bar))
NIL

FWIW, I remember that I didn't care about '(a b c) being a constant
either, when I made my first steps with Emacs Lisp, simply because I
didn't know about it.  Later I read somewhere that those literals
actually /are/ constants, thought ``Oops, aaaaarggh'' and henceforth
didn't modify them anymore.  Many examples in the literature happily
modify such constants, too, ``Object-Oriented Common Lisp'' by Stephen
Slade being a prominent example, I think (but the book is at home,
maybe my memory is wrong).

However, I wouldn't call that a ``bad design decision'', because in
many cases, a constant is exactly what you want.  Consider

CL-USER 28 > (defun blubb (x)
               (cons x '(1 2 3)))
BLUBB

CL-USER 29 > (compile 'blubb)
BLUBB
NIL
NIL

CL-USER 30 > (disassemble 'blubb)
206D4CE2:
       0:      3B25BC150020     cmp   esp, [200015BC]  ; T
       6:      7622             jbe   L1
       8:      80FD01           cmpb  ch, 1
      11:      751D             jne   L1
      13:      55               push  ebp
      14:      89E5             move  ebp, esp
      16:      FF7500           push  [ebp]
      19:      83ED04           sub   ebp, 4
      22:      8B7508           move  esi, [ebp+8]
      25:      897504           move  [ebp+4], esi
      28:      894508           move  [ebp+8], eax
      31:      B819256F20       move  eax, 206F2519    ; (1 2 3)
      36:      C9               leave 
      37:      E9BEFF4700       jmp   20B54CCA         ; #<function 20B54CCA>
L1:   42:      E8B11097FF       call  20045DC2         ; #<function 20045DC2>
      47:      90               nop   
      48:      90               nop   
      49:      90               nop   
NIL

See?  Now, the (1 2 3) object is always available at address 206F2519
and doesn't have to be constructed every time BLUBB is called.  Would
you really want to put such a serious performance penalty onto every
user just because some newbies cannot remember not to modify
constants?  You'd also change the semantics of the language; the CDRs
of the return values of different calls to BLUBB will always be EQL to
each other, now (being the same object).  You think it would be a
better design if that were not so?  Why?  Given that you didn't know
about list literals being constants, I must assume that you have just
begun learning Lisp; but you think that you should already propose
serious changes to the language semantics, as you go, so to speak?

Regards,
-- 
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x42B32FC9
From: Jacques Wainer
Subject: Re: weird function behavior
Date: 
Message-ID: <hxu1p9qjnb.fsf@xingu.dcc.unicamp.br>
Nils Goesche <······@cartan.de> writes:

| Jacques Wainer <······@ic.unicamp.br> writes:
| 
| > .. 
| > no where there is any indication that '(nil) is a constant. The
| > fact that the complier/evaluator considers that a constant to me is
| > a bad design decision. In fact, I could accept that the compiler, with
| > optimization set to a high level, would implement '(nil) as a
| > constant but I would not expect the evaluator in clisp, to perform
| > such optimization.
| > Before this event, I thought '(nil) to be operationally equivalent to
| > (list nil), but just notationally more convenient. 
| 


First I must publicly admit that I should have RTFM before posting on
no indication of teh constancy of '(nil). It is there in the Hyperspec
on "constant form" and on QUOTE. 

But on the bad decision thing I would like to develop the idea
a little further. I have the utmost respect for the people tath
developed Lisp though out its history, but some decisons are **on
hindsight** not as good as others.

As Nils points out  

| Well, they are not, and in several ways:
| ...
| 
| CL-USER 28 > (defun blubb (x)
|                (cons x '(1 2 3)))
| BLUBB
| 
| CL-USER 29 > (compile 'blubb)
| BLUBB
| NIL
| NIL
| 
| CL-USER 30 > (disassemble 'blubb)
| 206D4CE2:
|        0:      3B25BC150020     cmp   esp, [200015BC]  ; T
| ... 
| 
| See?  Now, the (1 2 3) object is always available at address 206F2519
| and doesn't have to be constructed every time BLUBB is called.  Would
| you really want to put such a serious performance penalty onto every
| user just because some newbies cannot remember not to modify
| constants?  

The argument is that for efficiency reasons one should make it a
constant. But one of the more common cannon of Lispers (and others) is
that premature concern for efficiency is the source of all (almost all
:-) evil. Here it seems that the cannon is correct: a (premature)
concern for efficiency made it necessary to introduce an unintuitive
behavior (again that is only my opinion) into the language. As the
Lisp cannon goes, if efficiency is your problem in that function then
compile it with a high level of optimization (which may change its
operational behavior and it is OK if it does, or at least one is
prepared for it).

Let me point to a clearer example of the cannon working. Take Java's
decision on having integer, float, and character as types outside its
standard type hierarchy. Because of "efficiency reasons" (at least it is
what I read in two textbooks) the language is ugly or inconvenient or
awkward to use (for example  using a hash to count things, for example
the multi signatures needed to define a method that works with
integers, floats and all objects). 



| You'd also change the semantics of the language; the CDRs
| of the return values of different calls to BLUBB will always be EQL to
| each other, now (being the same object).  You think it would be a
| better design if that were not so?  Why?  Given that you didn't know
| about list literals being constants, I must assume that you have just
| begun learning Lisp; but you think that you should already propose

If it is relevant to the discussion, that is not true. I am not a
novice lisper, but certainly I do not have the proficiency of most
readers of this group. That code was written by a student in an
undergrad course I teach that covers Java, Lisp and Prolog in a
semester, as examples of different programming paradigms. My problem
was that I've never encountered this "changing constant forms" before and
I could not explain to the student why the code behaved as it did. Now
I can explain it but I must mention early optimization decisions. 

| serious changes to the language semantics, as you go, so to speak?
| 
| Regards,
| -- 
| Nils Goesche
| "Don't ask for whom the <CTRL-G> tolls."
| 
| PGP key ID 0x42B32FC9

cheers.

jacques
From: Thomas F. Burdick
Subject: Re: weird function behavior
Date: 
Message-ID: <xcvznz16tbp.fsf@conquest.OCF.Berkeley.EDU>
Jacques Wainer <······@ic.unicamp.br> writes:

> Nils Goesche <······@cartan.de> writes:
> 
> | Jacques Wainer <······@ic.unicamp.br> writes:
> | 
> | > .. 
> | > no where there is any indication that '(nil) is a constant. The
> | > fact that the complier/evaluator considers that a constant to me is
> | > a bad design decision. In fact, I could accept that the compiler, with
> | > optimization set to a high level, would implement '(nil) as a
> | > constant but I would not expect the evaluator in clisp, to perform
> | > such optimization.
> | > Before this event, I thought '(nil) to be operationally equivalent to
> | > (list nil), but just notationally more convenient. 
> | 
> 
> First I must publicly admit that I should have RTFM before posting on
> no indication of teh constancy of '(nil). It is there in the Hyperspec
> on "constant form" and on QUOTE. 
> 
> But on the bad decision thing I would like to develop the idea
> a little further. I have the utmost respect for the people tath
> developed Lisp though out its history, but some decisons are **on
> hindsight** not as good as others.
> 
> As Nils points out  
> 
> | Well, they are not, and in several ways:
> | ...
> | 
> | CL-USER 28 > (defun blubb (x)
> |                (cons x '(1 2 3)))
> | BLUBB
> | 
> | CL-USER 29 > (compile 'blubb)
> | BLUBB
> | NIL
> | NIL
> | 
> | CL-USER 30 > (disassemble 'blubb)
> | 206D4CE2:
> |        0:      3B25BC150020     cmp   esp, [200015BC]  ; T
> | ... 
> | 
> | See?  Now, the (1 2 3) object is always available at address 206F2519
> | and doesn't have to be constructed every time BLUBB is called.  Would
> | you really want to put such a serious performance penalty onto every
> | user just because some newbies cannot remember not to modify
> | constants?  
> 
> The argument is that for efficiency reasons one should make it a
> constant.

Well, that's a nice optimization opened up by the definition of
literal objects, but I don't think it's its main justification.
Rather than talk about literal lists, why don't we talk about literal
strings, and get back to lists.

So, I've got a string:

  (defvar *foo* "one two three")

The spec says it's undefined what happens if I do

  (setf (subseq *foo* 0 3) "ONE")

It's nice that it's undefined, because that lets implementations just
clobber things when speed > safety.  However, I think the proper
behavior is for literals to be immutable.  The proprietary Lisp
compiler I'm working on goes to some lengths to ensure that all
literal objects are in read-only memory.  The thinking being that if
the user wrote "one two three", s/he meant what s/he wrote.  That is,
a literal object, created at read-time, not run-time.

A list is a sequence like any other.  Just as "one two three" is a
literal object that, IMO, should be immutable, but the spec says it's
undefined what happens when I mutate it, so the form '(1 2 3)
evaluates to a literal list.  If I do:

  (setf *foo* '(1 2 3))
  (setf (cdr *foo*) '(two three))

I'm in the same territory as my mutated string above.

But even in the world where you can modify literal objects, they are
still /literal/ objects.  When the reader reads:

  (list "one" "two" "three")

It makes a list containing the symbol LIST, and three strings.  If I write:

  (defun foo () (list "one" "two" "three"))
  (defun bar () (list (copy-seq "one") (copy-seq "two") (copy-seq "three")))

Notice that both functions return a fresh list each time.  However,

  (eq (first (foo)) (first (foo))) => T
  (eq (first (bar)) (first (bar))) => NIL

BAR creates a fresh list of fresh strings each time.  This isn't an
issue of efficiency, it's an issue of object identity.  You could
design an implementation for which each call to FOO created fresh
strings, but tagged them so that EQ would know what objects were EQ
and which weren't.  It would be stupid, but it would maintain the
illusion of object identity, so long as you didn't modify the objects.
In the style most Lisp users use, mainaining object identity is very
important.  And I think most Lisp users get it, up to the point of
modifying literals.  IE, I think they would be horrified by an
implementation for which

  (eq (first (foo)) (first (foo))) => NIL

even if they get confused by the effects of modifying literals.

> But one of the more common cannon of Lispers (and others) is
> that premature concern for efficiency is the source of all (almost all
> :-) evil. Here it seems that the cannon is correct: a (premature)
> concern for efficiency made it necessary to introduce an unintuitive
> behavior (again that is only my opinion) into the language. As the
> Lisp cannon goes, if efficiency is your problem in that function then
> compile it with a high level of optimization (which may change its
> operational behavior and it is OK if it does, or at least one is
> prepared for it).
> 
> Let me point to a clearer example of the cannon working. Take Java's
> decision on having integer, float, and character as types outside its
> standard type hierarchy. Because of "efficiency reasons" (at least it is
> what I read in two textbooks) the language is ugly or inconvenient or
> awkward to use (for example  using a hash to count things, for example
> the multi signatures needed to define a method that works with
> integers, floats and all objects). 
> 
> | You'd also change the semantics of the language; the CDRs
> | of the return values of different calls to BLUBB will always be EQL to
> | each other, now (being the same object).  You think it would be a
> | better design if that were not so?  Why?  Given that you didn't know
> | about list literals being constants, I must assume that you have just
> | begun learning Lisp; but you think that you should already propose
> 
> If it is relevant to the discussion, that is not true. I am not a
> novice lisper, but certainly I do not have the proficiency of most
> readers of this group. That code was written by a student in an
> undergrad course I teach that covers Java, Lisp and Prolog in a
> semester, as examples of different programming paradigms. My problem
> was that I've never encountered this "changing constant forms" before and
> I could not explain to the student why the code behaved as it did. Now
> I can explain it but I must mention early optimization decisions. 

Hopefully you don't still think this?  (If so, I did a lousy job
explaining myself, which is entirely possible).

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Duane Rettig
Subject: Re: weird function behavior
Date: 
Message-ID: <4d6vxnnc3.fsf@beta.franz.com>
Jacques Wainer <······@ic.unicamp.br> writes:

> The argument is that for efficiency reasons one should make it a
> constant. But one of the more common cannon of Lispers (and others) is
> that premature concern for efficiency is the source of all (almost all
> :-) evil.

I don't see a premature concern for efficiency here.  Where do you see it?

> Here it seems that the cannon is correct: a (premature)
> concern for efficiency made it necessary to introduce an unintuitive
> behavior (again that is only my opinion) into the language.

Yes, of course.  However, how does the CL specification removing the
assumptions a user may make about the implementation have to do with
premature concern with efficiency?  Perhaps you are confusing the
sample implementations people have described with the simple requirement
in the spec that constant objects be treated as immutable?

> As the
> Lisp cannon goes, if efficiency is your problem in that function then
> compile it with a high level of optimization

Yes.

> (which may change its
> operational behavior and it is OK if it does, or at least one is
> prepared for it).

No.  I want from my language (and get, for the most part) the assurance
that unless in the extreme case I am overly concerned with efficiency
and am willing to sacrifice correctness for speed, that I will get correct
results for correct programs.  Now, there are back recesses that most
implementations provide (mostly with the safety optimization quality set
to 0) where these sacrifices are sometimes made, but it is usually
done despite warnings from the vendors.  In general, cahnging optimization
settings should not change the correctness of a program.

> Let me point to a clearer example of the cannon working. Take Java's
> decision on having integer, float, and character as types outside its
> standard type hierarchy. Because of "efficiency reasons" (at least it is
> what I read in two textbooks) the language is ugly or inconvenient or
> awkward to use (for example  using a hash to count things, for example
> the multi signatures needed to define a method that works with
> integers, floats and all objects). 

However you define ugliness, I define it in terms of an unbridled need
for purity in a language, and thus to the extent that Java takes a
hybrid compromise, I call it beautiful.  So too, with Common Lisp, which
does an incredible job of maintaining balance in most areas.

> | You'd also change the semantics of the language; the CDRs
> | of the return values of different calls to BLUBB will always be EQL to
> | each other, now (being the same object).  You think it would be a
> | better design if that were not so?  Why?  Given that you didn't know
> | about list literals being constants, I must assume that you have just
> | begun learning Lisp; but you think that you should already propose
> 
> If it is relevant to the discussion, that is not true. I am not a
> novice lisper, but certainly I do not have the proficiency of most
> readers of this group. That code was written by a student in an
> undergrad course I teach that covers Java, Lisp and Prolog in a
> semester, as examples of different programming paradigms. My problem
> was that I've never encountered this "changing constant forms" before and
> I could not explain to the student why the code behaved as it did. Now
> I can explain it but I must mention early optimization decisions. 

I certainly hope you don't tie early optimization decisions to the
business about constants being immutable.  That would be a shame.

Think, for example, of things like repeatability and program integrity,
which is the more likely reason for requiring such immutability.

-- 
Duane Rettig          Franz Inc.            http://www.franz.com/ (www)
1995 University Ave Suite 275  Berkeley, CA 94704
Phone: (510) 548-3600; FAX: (510) 548-8253   ·····@Franz.COM (internet)
From: Jacques Wainer
Subject: Re: weird function behavior
Date: 
Message-ID: <hx8z6kiyxe.fsf@xingu.dcc.unicamp.br>
I must thank all who have tried to enlighten me on this issue. I think
that at least now I can express my displeasure in a language closer to
what my readers expect.

Here it goes, from clisp:

[8]> (eq '(nil) '(nil))
NIL
[9]> (eq (list nil) (list nil))
NIL

So it was not unreasonable to assume that '(nil) and (list nil) were
operationally equivalent. 

[14]> (defun y () (let ((a (list nil))) a))
Y
[15]> (defun x () (let ((a '(nil))) a))
X
[16]> (eq (x) (x))
T
[17]> (eq (y) (y))
NIL

which is the whole point of the issue. I lack the proper language
here, but in x the object '(nil) is created when the defun is
asserted, (at read time?) but in y the (list nil) is created when the
let is evaluated (when y is evaluated). A *new* object representing
(list nil) is created every time the let is "executed" in y, but the
*same* object representing '(nil) is binded to a in x.

It is this asymmetry that I find displeasing, and without the benefit
of history I attribute this feature on a decision to improve the
efficiency of the *execution* of the function x. Which is then
justified/explained by saying that '(nil) is a constant, and so one
can create it before the function is executed, whereas (list nil) is
not a constant.

And then, following on something that Erik wrote in this thread on the
moments in which objects are created in Lisp, I though " maybe because
' is a read macro, the object must be created at read time." But then:

[21]> (defun z () (let ((a (quote nil))) a))
Z
[22]> (eq (z) (z))
T

So it seems to me that it was a design decision to have the quote (and
the ') to behave  "as if" the object is created at read time. (This is
probably not what really happens, but from lines [8] and [15] it seems
that explaining as creation of the object at read time explains the
results).

That was my 2 cents

jacques
From: Duane Rettig
Subject: Re: weird function behavior
Date: 
Message-ID: <4g00s7oc4.fsf@beta.franz.com>
Jacques Wainer <······@ic.unicamp.br> writes:

> Here it goes, from clisp:

Your whole argument starts from this observation:
 
> [8]> (eq '(nil) '(nil))
> NIL

But even if _every_ current CL implementation returned the same
result, you would still not have the right to expect that this
is the result to expect.  The definition of a constant has nothing
to do with efficiency in this case (indeed, it would be _less_
efficient for an interpreter to track and merge all constants
in order to preserve eq-ness of like constants).  But the definition
of constant-ness gives the implementor rights as to how to implement,
and the user caveats as to what to expect (and what _not_ to expect).

Note here (in Allegro CL):

CL-USER(2): (defun foo () (eq '(nil) '(nil)))
FOO
CL-USER(3): (foo)
NIL
CL-USER(4): (compile 'foo)
FOO
NIL
NIL
CL-USER(5): (foo)
T
CL-USER(6): 

Again, this does not necessarily show what can be expected, but
what should _not_ be expected.

-- 
Duane Rettig          Franz Inc.            http://www.franz.com/ (www)
1995 University Ave Suite 275  Berkeley, CA 94704
Phone: (510) 548-3600; FAX: (510) 548-8253   ·····@Franz.COM (internet)
From: Erik Naggum
Subject: Re: weird function behavior
Date: 
Message-ID: <3230559216909207@naggum.net>
* Duane Rettig <·····@franz.com>
| Note here (in Allegro CL):
| 
| CL-USER(2): (defun foo () (eq '(nil) '(nil)))
| FOO
| CL-USER(3): (foo)
| NIL
| CL-USER(4): (compile 'foo)
| FOO
| NIL
| NIL
| CL-USER(5): (foo)
| T
| CL-USER(6): 
| 
| Again, this does not necessarily show what can be expected, but
| what should _not_ be expected.

  This is a great example to show why the consequences of modifying a
  literal are _undefined_.  Even if it actually works to modify some part
  of the source code, or some object that is re-created when loading a
  compiled file, the compiler has a license to coalesce literals because
  they are not expected to be modified.

  E.g., a pathological example that may show just how messed up some of
  these things can get:

(defmacro mumble (&body body)
  (list* 'let '((x '(nil))) body))
=> mumble

(defun fumble ()
  (mumble (setf (car x) 0)))
=> fumble

(mumble x)
=> (nil)

(fumble)
=> 0

(mumble x)
=> (0)
  
  I leave it to the reader to figure out why it does not (generally) work
  with the more normal backquoted form of the macro body.
-- 
  In a fight against something, the fight has value, victory has none.
  In a fight for something, the fight is a loss, victory merely relief.

  70 percent of American adults do not understand the scientific process.
From: Coby Beck
Subject: Re: weird function behavior
Date: 
Message-ID: <BwGE8.80485$xS2.6603803@news1.calgary.shaw.ca>
Jacques Wainer <······@ic.unicamp.br> wrote in message
···················@xingu.dcc.unicamp.br...
>
> I must thank all who have tried to enlighten me on this issue. I think
> that at least now I can express my displeasure in a language closer to
> what my readers expect.
>
> Here it goes, from clisp:
>
> [8]> (eq '(nil) '(nil))
> NIL
> [9]> (eq (list nil) (list nil))
> NIL
>
> So it was not unreasonable to assume that '(nil) and (list nil) were
> operationally equivalent.
>
> [14]> (defun y () (let ((a (list nil))) a))
> Y
> [15]> (defun x () (let ((a '(nil))) a))
> X
> [16]> (eq (x) (x))
> T
> [17]> (eq (y) (y))
> NIL
>
> which is the whole point of the issue. I lack the proper language
> here, but in x the object '(nil) is created when the defun is
> asserted, (at read time?) but in y the (list nil) is created when the
> let is evaluated (when y is evaluated). A *new* object representing
> (list nil) is created every time the let is "executed" in y, but the
> *same* object representing '(nil) is binded to a in x.
>
> It is this asymmetry that I find displeasing, and without the benefit
> of history I attribute this feature on a decision to improve the
> efficiency of the *execution* of the function x.

Why do you expect symmetry?  (LIST NIL) is not (QUOTE (NIL)).  You thought
'() was notational short hand for (LIST ) but it is not, they are
fundamentally different.  You should no longer expect symmetry and should
not be "displeased" when you don't get it.  I don't think you have totally
let go of your prior way of looking at '()

--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Ingvar Mattsson
Subject: Re: weird function behavior
Date: 
Message-ID: <87y9ekz5tl.fsf@gruk.tech.ensign.ftech.net>
Jacques Wainer <······@ic.unicamp.br> writes:

> I must thank all who have tried to enlighten me on this issue. I think
> that at least now I can express my displeasure in a language closer to
> what my readers expect.
> 
> Here it goes, from clisp:
> 
> [8]> (eq '(nil) '(nil))
> NIL
> [9]> (eq (list nil) (list nil))
> NIL
> 
> So it was not unreasonable to assume that '(nil) and (list nil) were
> operationally equivalent. 

Hrm. Thing is that the "constantness" of (QUOTE ...) happens at
read-time and an implementation is allowed to not fold two
(QUOTE (... )) together. That is, '(A B C D) and '(A B C D) may be two
different lists, with four elements, being the same symbols. However,
  (defun foo () '(A B C D))
will return the same list every time, since its identity was
established at the read-time of the function.

> [14]> (defun y () (let ((a (list nil))) a))
> Y
> [15]> (defun x () (let ((a '(nil))) a))
> X
> [16]> (eq (x) (x))
> T
> [17]> (eq (y) (y))
> NIL
> 
> which is the whole point of the issue. I lack the proper language
> here, but in x the object '(nil) is created when the defun is
> asserted, (at read time?) but in y the (list nil) is created when the
> let is evaluated (when y is evaluated). A *new* object representing
> (list nil) is created every time the let is "executed" in y, but the
> *same* object representing '(nil) is binded to a in x.

Read-time (possibly with constant-folding at compile-time) versus
execution-time.

//Ingvar
-- 
My posts are fair game for anybody who wants to distribute the countless
pearls of wisdom sprinkled in them, as long as I'm attributed.
	-- Martin Wisse, in a.f.p
From: Thomas F. Burdick
Subject: Re: weird function behavior
Date: 
Message-ID: <xcvvg9ndfkh.fsf@famine.OCF.Berkeley.EDU>
You're very very confused on the basics of what Lisp programs are.
What would you expect from the following Lisp code:

  (defun foo () "test")
  (defun bar () (copy-seq "test"))

  (eq (foo) (foo))
  (eq (bar) (bar))

What would you expect from the following C code:

  char * foo (void) {
    char *s = "test";
    return s;
  }

  char * bar (void) {
    char *s = malloc (sizeof(char) * 5);
    strncpy (s, "test");
    return s;
  }

  /* ... */
  (foo() == foo())
  /* ... */
  (bar() == bar())

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Kent M Pitman
Subject: Re: weird function behavior
Date: 
Message-ID: <sfwbsbg42lw.fsf@shell01.TheWorld.com>
Jacques Wainer <······@ic.unicamp.br> writes:

> I must thank all who have tried to enlighten me on this issue. I think
> that at least now I can express my displeasure in a language closer to
> what my readers expect.
> 
> Here it goes, from clisp:
> 
> [8]> (eq '(nil) '(nil))
> NIL
> [9]> (eq (list nil) (list nil))
> NIL
> 
> So it was not unreasonable to assume that '(nil) and (list nil) were
> operationally equivalent. 

The problem is that you're defining
 (defun operationally-equivalent-p (form1 form2)
   (let ((test1 `(eq ,form1 ,form1))
         (test2 `(eq ,form2 ,form2)))
     (let ((result1 (eval test1))
           (result2 (eval test2)))
       (and (not result1) ;do you even care about this test? i couldn't tell
            (eq result1 result2)))))
This is both the weakest and weirdest definition of operational equivalence
I've ever seen.

By your apparent logic:

(eq '(nil) '(nil)) => NIL
(eq (list (make-symbol "NIL")) (list (make-symbol "NIL"))) => NIL

So it is not unreasonable to assume that '(nil) and (list (make-symbol "NIL"))
were operationally equivalent.

(eq '(nil) '(nil)) => NIL
(eq (if (boundp '*foo*) (setq *foo* 17) (incf *foo*))
    (if (boundp '*foo*) (setq *foo* 17) (incf *foo*)))
=> NIL

So it is not unreasonable to assume that '(nil) and 
(if (boundp '*foo*) (setq *foo* 17) (incf *foo*)) were operationally
equivalent.

- - - - 

You are also exploiting concrete understanding of a particular
implementation in order to understand a general rule that applies to
all implementations.  HINT: DO NOT DO THIS.  This will not serve you
meaningfully in any of your understanding of the language.  The
language is not designed in such a way that attempting to infer the
spec from the behavior in many cases is easy or even possible.  Some
things certainly are possible to deduce, but many things aren't.  For
example, the spec might say that a certain effect has undefined
consequences, leaving one implementation to signal an error while
another retuns some 'useful' result.  This can be quite confusing to
users who try to infer a language definition from a particular
implementation, PARTICULARLY to those who try to infer it from the
implementation where a useful effect happens, since there may be
another implementation with a distinct 'useful' effect that is not the
same.

> which is the whole point of the issue. I lack the proper language
> here, but in x the object '(nil) is created when the defun is
> asserted, (at read time?) but in y the (list nil) is created when the
> let is evaluated (when y is evaluated). A *new* object representing
> (list nil) is created every time the let is "executed" in y, but the
> *same* object representing '(nil) is binded to a in x.
> 
> It is this asymmetry that I find displeasing, and without the benefit
> of history I attribute this feature on a decision to improve the
> efficiency of the *execution* of the function x. Which is then
> justified/explained by saying that '(nil) is a constant, and so one
> can create it before the function is executed, whereas (list nil) is
> not a constant.

No, the decision is based on a VERY IMPORTANT thing about Lisp which
is that you have tight control of a number of decision times that are
blurred in other languages.

You are assuming that the variabilities and binding times are random
because either you apparently haven't read the spec to find when the
times are described, or because someone whose book you read that was
not the spec but purported to summarize it has offered you misleading
information.  It's common for people to make mistakes of this kind, but
it is not reasonable or fair for you to make your first assumption be
that the language is ill-designed.  Your first guess should include the
possibility that "the language is more complex than you thought it was".

> And then, following on something that Erik wrote in this thread on the
> moments in which objects are created in Lisp, I though " maybe because
> ' is a read macro, the object must be created at read time." But then:
> 
> [21]> (defun z () (let ((a (quote nil))) a))
> Z
> [22]> (eq (z) (z))
> T

You really need to read the seciton in the spec on externalization of 
objects, and how that affects identity.
 
> So it seems to me that it was a design decision to have the quote (and
> the ') to behave  "as if" the object is created at read time.

File compilation is permitted to relocate objects, so that complicates
things some.  Literal objects that seem distinct can be coalesced, and objects
that seem identical can be split, if file compilation (and hence object
externalization) is involved.  However, with "in-core" compilation, these
effects should not be in play.

> (This is
> probably not what really happens, but from lines [8] and [15] it seems
> that explaining as creation of the object at read time explains the
> results).

Yes, I think that's right.
From: Alain Picard
Subject: Re: weird function behavior
Date: 
Message-ID: <86lmakcrk2.fsf@gondolin.local.net>
Jacques Wainer <······@ic.unicamp.br> writes:

> 
> Here it goes, from clisp:
> 
> [8]> (eq '(nil) '(nil))
> NIL
> [9]> (eq (list nil) (list nil))
> NIL
> 
> So it was not unreasonable to assume that '(nil) and (list nil) were
> operationally equivalent. 

One of the wonderful things about Common Lisp is that it is
not defined by an implementation, unlike other well known scripting
"languages".

The correct way to think about this is to first find out from the spec
if your program is _valid_.  If you get correct results from an invalid
program, well, you're lucky, but I wouldn't want to depend on such code.
From: Geoff Summerhayes
Subject: Re: weird function behavior
Date: 
Message-ID: <30AE8.78505$GG6.6844805@news3.calgary.shaw.ca>
"Jacques Wainer" <······@ic.unicamp.br> wrote in message
···················@xingu.dcc.unicamp.br...
>
> The argument is that for efficiency reasons one should make it a
> constant.

You have it backwards. It is constant by definition, the
observed behaviour takes place because the implementation
is not required to signal an error, do nothing, or <shudder>
cover up the mistake and copy when the attempt to modify the
constant is made.

IOW, the behavior you see is because the Lisp implementation,
for the sake of efficiency, decided to allow the modification
to continue by treating the constant as a variable without the
additional protection checks.

You get the same thing in other languages. In C for example:

    char* a="Hello, world";
    strcpy(a,"foo");
    printf("%s",a);

Will this run? Depends on the compiler, it is undefined
behaviour, it could print "foo", "Hello, world", or segfault.

Computer languages would have to be much bigger and slower
if they had to catch all <lol> the programmer's possible
errors.

----------
Geoff
From: Michael Kappert
Subject: Re: weird function behavior
Date: 
Message-ID: <3CE2CC8C.3F3DFBF6@gmx.net>
Jacques Wainer schrieb:

> | Jacques Wainer <······@ic.unicamp.br> writes:
> | > Before this event, I thought '(nil) to be operationally equivalent to
> | > (list nil), but just notationally more convenient.

Ok, but now you know they are not.

> But on the bad decision thing I would like to develop the idea
> a little further. I have the utmost respect for the people tath
> developed Lisp though out its history, but some decisons are **on
> hindsight** not as good as others.
[...] 
> I could not explain to the student why the code behaved as it did. Now
> I can explain it but I must mention early optimization decisions.

No, you don't.
You just gave a simple and correct explanation yourself -
'(nil) and (list nil) are not the same thing.
The former is a constant, the latter is not.

> The argument is that for efficiency reasons one should make it a
> constant.

Is this the source of your confusion?
Who should make it a constant? The implementation, yes, but,
again, the user has the option to not use a constant, because
(list <thing>) is *not* a constant.

Michael
From: Coby Beck
Subject: Re: weird function behavior
Date: 
Message-ID: <jKxE8.76310$uE2.5858511@news2.calgary.shaw.ca>
Nils Goesche <······@cartan.de> wrote in message
···················@pc022.bln.elmeg.de...
> Jacques Wainer <······@ic.unicamp.br> writes:
>
> > Erik Naggum <····@naggum.net> writes:
> >
> > | * Jacques Wainer
> > | | (defun prob()
> > | |   (let ((x '(nil)))
> > | |     (push 1 (elt x 0))))
> > |
> > |   Where did you get the idea that you should use a quoted constant in
your
> > |   code to begin with?  I am actually seriously curious about this,
because
> >
> > no where there is any indication that '(nil) is a constant. The
> > fact that the complier/evaluator considers that a constant to me is
> > a bad design decision. In fact, I could accept that the compiler, with
> > optimization set to a high level, would implement '(nil) as a
> > constant but I would not expect the evaluator in clisp, to perform
> > such optimization.
> > Before this event, I thought '(nil) to be operationally equivalent to
> > (list nil), but just notationally more convenient.
>
> Well, they are not, and in several ways:
>
> CL-USER 24 > (defun foo ()
>                '(nil))
> FOO
>
> CL-USER 25 > (defun bar ()
>                (list nil))
> BAR
>
> CL-USER 26 > (eql (foo) (foo))
> T

in fact:
CL-USER 26.5 > (eq (foo) (foo))
T

> CL-USER 27 > (eql (bar) (bar))
> NIL
>
[snip]
> better design if that were not so?  Why?  Given that you didn't know
> about list literals being constants, I must assume that you have just
> begun learning Lisp

Aside from being incorrect (IIRC the OP said he was teaching - though maybe
not lisp specifically) this is not a fair assumption.  If the OP were a
working programmer, working in lisp, that would be a more reasonable
conclusion.  But it's easy to go for years (lifetimes!) with hidden
misunderstandings when your usage patterns remain constant, such as in an
acedemic environment where the curriculum does not change.

--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Ed L Cashin
Subject: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <878z5snth3.fsf_-_@cs.uga.edu>
Nils Goesche <······@cartan.de> writes:

...
> FWIW, I remember that I didn't care about '(a b c) being a constant
> either, when I made my first steps with Emacs Lisp, simply because I
> didn't know about it.  Later I read somewhere that those literals
> actually /are/ constants, thought ``Oops, aaaaarggh'' and henceforth
> didn't modify them anymore.  Many examples in the literature happily
> modify such constants, too, ``Object-Oriented Common Lisp'' by Stephen
> Slade being a prominent example, I think (but the book is at home,
> maybe my memory is wrong).

Just to clarify, is the following code incorrect because it modifies a
constant list?


  (let ((x '(1 2 3)))
    (setf (car x) 2)
    x)


-- 
--Ed L Cashin            |   PGP public key:
  ·······@uga.edu        |   http://noserose.net/e/pgp/
From: Thomas F. Burdick
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <xcvlm9skyw9.fsf@apocalypse.OCF.Berkeley.EDU>
Ed L Cashin <·······@uga.edu> writes:

> Nils Goesche <······@cartan.de> writes:
> 
> ...
> > FWIW, I remember that I didn't care about '(a b c) being a constant
> > either, when I made my first steps with Emacs Lisp, simply because I
> > didn't know about it.  Later I read somewhere that those literals
> > actually /are/ constants, thought ``Oops, aaaaarggh'' and henceforth
> > didn't modify them anymore.  Many examples in the literature happily
> > modify such constants, too, ``Object-Oriented Common Lisp'' by Stephen
> > Slade being a prominent example, I think (but the book is at home,
> > maybe my memory is wrong).
> 
> Just to clarify, is the following code incorrect because it modifies a
> constant list?
> 
> 
>   (let ((x '(1 2 3)))
>     (setf (car x) 2)
>     x)

Yes, that's non-conforming code.  Imagine all the cons cells in your
quoted list being in read-only memory.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Andy
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <3CFFBC74.68A6C140@smi.de>
"Thomas F. Burdick" wrote:
> >
> > Just to clarify, is the following code incorrect because it modifies a
> > constant list?
> >
> >
> >   (let ((x '(1 2 3)))
> >     (setf (car x) 2)
> >     x)
> 
> Yes, that's non-conforming code.  Imagine all the cons cells in your
> quoted list being in read-only memory.
> 
Don't hurt me but i don't understand it. In the Hyperspec i found:

"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"

But that doesn't hold for x since x is affected by the environment. I think that
'(1 2 3) is a list of constants but itself does not be constant.

Can please anyone explain why i'm wrong.
Thanks in advance

Best
AHz
From: Ed L Cashin
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <87zny8mbdu.fsf@cs.uga.edu>
Andy <···@smi.de> writes:

> "Thomas F. Burdick" wrote:
> > >
> > > Just to clarify, is the following code incorrect because it modifies a
> > > constant list?
> > >
> > >
> > >   (let ((x '(1 2 3)))
> > >     (setf (car x) 2)
> > >     x)
> > 
> > Yes, that's non-conforming code.  Imagine all the cons cells in your
> > quoted list being in read-only memory.
> 
> Don't hurt me but i don't understand it. 

Well I certainly can't blame you.  I was kind of surprised that
although it seems like a really big deal, I don't remember the lisp
books and intros that I've read being explicit about it.

The issue deserves heavy emphasis in introductory contexts, IMHO,
since at the REPL, there's no warning that the code is wrong.  I guess
it would be better for the lisp implementation to signal an error, but
it's only a newbie's guess.

-- 
--Ed L Cashin            |   PGP public key:
  ·······@uga.edu        |   http://noserose.net/e/pgp/
From: Barry Margolin
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <iIPL8.33$Se2.205@paloalto-snr2.gtei.net>
In article <·················@smi.de>, Andy  <···@smi.de> wrote:
>> >   (let ((x '(1 2 3)))
>> >     (setf (car x) 2)
>> >     x)
>Don't hurt me but i don't understand it. In the Hyperspec i found:
>
>"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"
>
>But that doesn't hold for x since x is affected by the environment. I think that
>'(1 2 3) is a list of constants but itself does not be constant.

Any expression of the form (quote <thing>) (which is what '<thing> is short
for) always yields the same value: <thing>.  The environment does not
affect this.

x isn't a constant, but the list it refers to is.  So

(setf x (cons 2 (cdr x)))

is OK, but

(setf (car x) 2)

isn't.

-- 
Barry Margolin, ······@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.
From: Andy
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <3CFFE6CA.D1DC6D6F@snafu.de>
Barry Margolin wrote:
> 
> In article <·················@smi.de>, Andy  <···@smi.de> wrote:
> >> >   (let ((x '(1 2 3)))
> >> >     (setf (car x) 2)
> >> >     x)
> >Don't hurt me but i don't understand it. In the Hyperspec i found:
> >
> >"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"
> >
> >But that doesn't hold for x since x is affected by the environment. I think that
> >'(1 2 3) is a list of constants but itself does not be constant.
> 
> Any expression of the form (quote <thing>) (which is what '<thing> is short
> for) always yields the same value: <thing>.  The environment does not
> affect this.
> 
> x isn't a constant, but the list it refers to is.  So
> 
Sorry, my nerd questions. I agree that a form whose car is "qoute" is constant. 
But in the "let" form x the initial value is evaluated.  
Doesn't that mean that lisp evaluates (quote (1 2 3)) ? That is (1 2 3).
So, x points to (1 2 3) not to '(1 2 3) ? And then we are not talking about a
constant list, do we ?
Maybe my fault comes from the idea i found in my books (Graham's Ansi CL & PAIP).
There i found pictures showing that lists are represented as cons cells chains.
For me that leads to the assumption that a list can't be constant until i advice
the compiler to believe that or the compiler find out that the list is never
changed.
It still looks worse to me, sorry. Any help is realy welcome.
Best
AHz
From: Barry Margolin
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <DXRL8.37$Se2.473@paloalto-snr2.gtei.net>
In article <·················@snafu.de>, Andy  <···@snafu.de> wrote:
>Sorry, my nerd questions. I agree that a form whose car is "qoute" is constant. 
>But in the "let" form x the initial value is evaluated.  
>Doesn't that mean that lisp evaluates (quote (1 2 3)) ? That is (1 2 3).
>So, x points to (1 2 3) not to '(1 2 3) ? And then we are not talking about a
>constant list, do we ?

The restriction in section 3.7.1 is against destructively modifying a
"literal object".  The glossary entry for "literal" says:

  literal adj. (of an object) referenced directly in a program rather than
  being computed by the program; that is, appearing as data in a quote form,
  or, if the object is a self-evaluating object, appearing as unquoted
  data. ``In the form (cons "one" '("two")), the expressions "one", ("two"),
  and "two" are literal objects.''

In

(let ((x '(1 2 3)))
  (setf (car x) 2))

the expression (1 2 3) is a literal object that is returned by the quote
form, and X is initialized to that literal object.  

The relationship with "constant form" is that all expressions that result
in literal objects are also constant forms (but there are constant forms
that do not result in literal objects, such as evaluation of a variable
defined with DEFCONSTANT).

-- 
Barry Margolin, ······@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.
From: Andy
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <3D008733.1C9AA392@smi.de>
Barry Margolin wrote:
> 
> The restriction in section 3.7.1 is against destructively modifying a
> "literal object".  The glossary entry for "literal" says:
> 
That's what i was missing. I looked for constant forms instead.
Thank you very much

Best
AHz
From: Andy
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <3CFFE714.D973B07B@snafu.de>
Barry Margolin wrote:
> 
> In article <·················@smi.de>, Andy  <···@smi.de> wrote:
> >> >   (let ((x '(1 2 3)))
> >> >     (setf (car x) 2)
> >> >     x)
> >Don't hurt me but i don't understand it. In the Hyperspec i found:
> >
> >"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"
> >
> >But that doesn't hold for x since x is affected by the environment. I think that
> >'(1 2 3) is a list of constants but itself does not be constant.
> 
> Any expression of the form (quote <thing>) (which is what '<thing> is short
> for) always yields the same value: <thing>.  The environment does not
> affect this.
> 
> x isn't a constant, but the list it refers to is.  So
> 
Sorry, my nerd questions. I agree that a form whose car is "qoute" is constant. 
But in the "let" form x the initial value is evaluated.  
Doesn't that mean that lisp evaluates (quote (1 2 3)) ? That is (1 2 3).
So, x points to (1 2 3) not to '(1 2 3) ? And then we are not talking about a
constant list, do we ?
Maybe my fault comes from the idea i found in my books (Graham's Ansi CL & PAIP).
There i found pictures showing that lists are represented as cons cells chains.
For me that leads to the assumption that a list can't be constant until i advice
the compiler to believe that or the compiler find out that the list is never
changed.
It still looks worse to me, sorry. Any help is realy welcome.
Best
AHz
From: Coby Beck
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <vCWL8.198396$xS2.15222109@news1.calgary.shaw.ca>
Andy <···@snafu.de> wrote in message ······················@snafu.de...
> Barry Margolin wrote:
> >
> > In article <·················@smi.de>, Andy  <···@smi.de> wrote:
> > >> >   (let ((x '(1 2 3)))
> > >> >     (setf (car x) 2)
> > >> >     x)
> > >Don't hurt me but i don't understand it. In the Hyperspec i found:
> > >
> > >"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"
> > >
> > >But that doesn't hold for x since x is affected by the environment. I
think that
> > >'(1 2 3) is a list of constants but itself does not be constant.
> >
> > Any expression of the form (quote <thing>) (which is what '<thing> is
short
> > for) always yields the same value: <thing>.  The environment does not
> > affect this.
> >
> > x isn't a constant, but the list it refers to is.  So
> >
> Sorry, my nerd questions. I agree that a form whose car is "qoute" is
constant.

Just to be a stickler for language here, it is not a matter to agree to or
not, it is a fact as defined by the language specification.  This is
important to remember when talking about it.

> But in the "let" form x the initial value is evaluated.
> Doesn't that mean that lisp evaluates (quote (1 2 3)) ? That is (1 2 3).
> So, x points to (1 2 3) not to '(1 2 3) ? And then we are not talking
about a
> constant list, do we ?

The difference is that between (list 1 2 3) and '(1 2 3).  After evaluation,
they look the same and have the same data and the same structure, but you
must be careful how you use it if you want conforming code.

> Maybe my fault comes from the idea i found in my books (Graham's Ansi CL &
PAIP).
> There i found pictures showing that lists are represented as cons cells
chains.
> For me that leads to the assumption that a list can't be constant until i
advice
> the compiler

When you use a quote, you *are* advising the compiler that your list is a
constant.

--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Jochen Schmidt
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <adpcc9$lu6$1@rznews2.rrze.uni-erlangen.de>
Andy wrote:

> Barry Margolin wrote:
>> 
>> In article <·················@smi.de>, Andy  <···@smi.de> wrote:
>> >> >   (let ((x '(1 2 3)))
>> >> >     (setf (car x) 2)
>> >> >     x)
>> >Don't hurt me but i don't understand it. In the Hyperspec i found:
>> >
>> >"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"
>> >
>> >But that doesn't hold for x since x is affected by the environment. I
>> >think that '(1 2 3) is a list of constants but itself does not be
>> >constant.
>> 
>> Any expression of the form (quote <thing>) (which is what '<thing> is
>> short
>> for) always yields the same value: <thing>.  The environment does not
>> affect this.
>> 
>> x isn't a constant, but the list it refers to is.  So
>> 
> Sorry, my nerd questions. I agree that a form whose car is "qoute" is
> constant. But in the "let" form x the initial value is evaluated.
> Doesn't that mean that lisp evaluates (quote (1 2 3)) ? That is (1 2 3).
> So, x points to (1 2 3) not to '(1 2 3) ? And then we are not talking
> about a constant list, do we ?

We do. Neither '(1 2 3) nor (1 2 3) are lists. They are printed 
representations of what can be a list (or not). A list (in Lisp) is built 
from cons cells which are datastructures with two slots. Lisp code is 
written as lists and atoms. The interpreter or compiler works on this 
list-structures to evaluate or compile the code.

(+ 1 (* 3 4))

[+|  ]->[1|  ]->[  |  ]->NIL
                     |
                    [* |  ]->[3 |  ]->[4 |  ]->NIL

Are two ways two look at how lispcode is represented.

As you can see in the above example we use literal numbers like 3, 4 and 1 
as data in our program. What if we now want two represent a program which 
uses literal _list_ data?
The problem is now - if we use lists and symbols for sourcecode 
representation that we cannot express "literal" list or symbol data 
anymore. We need a functionality to express that we mean a list structure 
as data and not as code that should get evaluated. We do this with the 
QUOTE special form. If the compiler is walking the code tree and runs into 
a sublist which begins with QUOTE then he knows that the next element is a 
literal object. A list encountered within this sublist is literal program 
data and not sourcecode. A symbol encountered within this sublist is not a 
variable reference but a literal symbol.

A                  - Variable reference
(quote A)      - A literal symbol (a datastructure)
(fn)               - A function call
(quote (fn))   - A literal list containing a symbol.

> Maybe my fault comes from the idea i found in my books (Graham's Ansi CL &
> PAIP). There i found pictures showing that lists are represented as cons
> cells chains. For me that leads to the assumption that a list can't be
> constant until i advice the compiler to believe that or the compiler find
> out that the list is never changed.

This is wrong. You can imagine a literal list as being built from cons 
cells which are stored in read only memory. You *cannot* change the car or 
cdr of any of the cons cells then so you can not change the structure of 
the list.  A compiler is allowed to coalesce all equal literals two one.  
So in

(let ((a '(1 2 3)))
   a)
...
(let ((b '(1 2 3)))
   b)

a and b may denote the same list.
So if you modify b you will change a which is somewhere else in the code 
and may have semantically nothing to do with b.

ciao,
Jochen

--
http://www.dataheaven.de
From: Jochen Schmidt
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <adpcij$lu6$2@rznews2.rrze.uni-erlangen.de>
Sorry for the mangled box-pointer diagram.
I hope this comes better:

[+| ]->[1| ]->[ | ]->NIL
               |
              [*| ]->[3| ]->[4| ]->NIL

ciao,
Jochen

--
http://www.dataheaven.de
From: Jochen Schmidt
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <adpd70$dq3$1@rznews2.rrze.uni-erlangen.de>
Jochen Schmidt wrote:

> So in
> 
> (let ((a '(1 2 3)))
>    a)
> ...
> (let ((b '(1 2 3)))
>    b)
> 
> a and b may denote the same list.
> So if you modify b you will change a which is somewhere else in the code
> and may have semantically nothing to do with b.

This may be misleading. I meant "if you modify the list in b you will 
change the list in b too since it is the same object".

ciao,
Jochen

--
http://www.dataheaven.de
From: Thomas A. Russ
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <ymi7klawxam.fsf@sevak.isi.edu>
Andy <···@snafu.de> writes:

...
> For me that leads to the assumption that a list can't be constant until i advice
> the compiler to believe that or the compiler find out that the list is never
> changed.

Well, the way you tell the compiler that a list is constant is to use
QUOTE.  For a non-constant list, you will need to build it yourself:

 (let (x (list 1 2 3))
   ...)

or possibly using backquote instead of quote:

  (let (x `(1 2 3))
    ...)


-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Kaz Kylheku
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <slrnag4g0o.s2g.kaz@localhost.localdomain>
On 07 Jun 2002 15:15:13 -0700, Thomas A. Russ <···@sevak.isi.edu> wrote:
>Andy <···@snafu.de> writes:
>
>...
>> For me that leads to the assumption that a list can't be constant until i advice
>> the compiler to believe that or the compiler find out that the list is never
>> changed.
>
>Well, the way you tell the compiler that a list is constant is to use
>QUOTE.  For a non-constant list, you will need to build it yourself:
>
> (let (x (list 1 2 3))
>   ...)
>
>or possibly using backquote instead of quote:
>
>  (let (x `(1 2 3))
>    ...)

CLHS 2.4.6: ``The constructed copy of the template might or might not share
list structure with the template itself.'' 

Thus backquote templates are not required to produce non-constant lists.

For example `(,x 1 2 3) may produce a list whose first cell is freshly
consed, but whose remaining cells are constant, as in (cons x '(1 2 3)).

And `(1 2 3) might behave exactly as '(1 2 3).
From: Thomas F. Burdick
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <xcvadq6kd9g.fsf@conquest.OCF.Berkeley.EDU>
Andy <···@smi.de> writes:

> "Thomas F. Burdick" wrote:
> > >
> > > Just to clarify, is the following code incorrect because it modifies a
> > > constant list?
> > >
> > >
> > >   (let ((x '(1 2 3)))
> > >     (setf (car x) 2)
> > >     x)
> > 
> > Yes, that's non-conforming code.  Imagine all the cons cells in your
> > quoted list being in read-only memory.
> > 
> Don't hurt me but i don't understand it. In the Hyperspec i found:
> 
> "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"
> 
> But that doesn't hold for x since x is affected by the environment. I think that
> '(1 2 3) is a list of constants but itself does not be constant.

In my mental model of the Lisp world, anything returned by QUOTE is in
read-only space.  So for example, in '(1 2 (a (foo . bar) c) 4 5), all
nine of those cons cells are read-only.  The compiler I'm working on
expresses this literally; it goes to some lengths to make sure that
all literal data is in read-only memory, so you'll get an error if you
try to modify it.  It would be really nice if the major lisp compilers
did this.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Erik Naggum
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <3232481348218721@naggum.net>
* Thomas F. Burdick
| In my mental model of the Lisp world, anything returned by QUOTE is in
| read-only space.  So for example, in '(1 2 (a (foo . bar) c) 4 5), all
| nine of those cons cells are read-only.  The compiler I'm working on
| expresses this literally; it goes to some lengths to make sure that all
| literal data is in read-only memory, so you'll get an error if you try to
| modify it.  It would be really nice if the major lisp compilers did this.

  Are all self-quoting objects that are created by the reader turned into
  read-only objects or do you make a special case for quote?  The typical
  example is the literal string.  The above could easily be read to imply
  that only the special operator quote produces literals, which you may not
  have meant.  I see a definite problem with identifying, remembering, and
  maintaining the creation time of objects.  Unless you _only_ arrange for
  the loader to create read-only objects out of the literals that survive
  compilation, I see a truckload of problems here.  E.g., the reader may
  well cause portions of an evaluated back-quoted form to share structure
  with the original list.  Incidentally, if you treat all pathnames as
  read-only objects (since there are no mutators for them), you could also
  intern them and save on translation to namestrings.
-- 
  In a fight against something, the fight has value, victory has none.
  In a fight for something, the fight is a loss, victory merely relief.

  70 percent of American adults do not understand the scientific process.
From: Thomas F. Burdick
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <xcvptyy674i.fsf@conquest.OCF.Berkeley.EDU>
Erik Naggum <····@naggum.net> writes:

> * Thomas F. Burdick
> | In my mental model of the Lisp world, anything returned by QUOTE is in
> | read-only space.  So for example, in '(1 2 (a (foo . bar) c) 4 5), all
> | nine of those cons cells are read-only.  The compiler I'm working on
> | expresses this literally; it goes to some lengths to make sure that all
> | literal data is in read-only memory, so you'll get an error if you try to
> | modify it.  It would be really nice if the major lisp compilers did this.
> 
>   Are all self-quoting objects that are created by the reader turned into
>   read-only objects or do you make a special case for quote?  The typical
>   example is the literal string.  The above could easily be read to imply
>   that only the special operator quote produces literals, which you may not
>   have meant.

Right, any literal object goes into read-only space, including those
that come from QUOTE.

>   I see a definite problem with identifying, remembering, and
>   maintaining the creation time of objects.  Unless you _only_ arrange for
>   the loader to create read-only objects out of the literals that survive
>   compilation, I see a truckload of problems here.  E.g., the reader may
>   well cause portions of an evaluated back-quoted form to share structure
>   with the original list.

The compiler keeps track of all the literal objects in the source, and
arranges for the loader to load them into RO space.  So, yes,
something has to survive compilation to get put in RO space.  And this
works for all compiled code because COMPILE effectively sends source
to the compiler then object code to the loader (and there currently is
no interpreter).

>   Incidentally, if you treat all pathnames as read-only objects
>   (since there are no mutators for them), you could also intern them
>   and save on translation to namestrings.

Huh, I hadn't thought of that, thanks.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Andy
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <3D048AAA.5DDC2D9@smi.de>
"Thomas F. Burdick" wrote:
> 
> Andy <···@smi.de> writes:
> 
> > "Thomas F. Burdick" wrote:
> > > >
> > > > Just to clarify, is the following code incorrect because it modifies a
> > > > constant list?
> > > >
> > > >
> > > >   (let ((x '(1 2 3)))
> > > >     (setf (car x) 2)
> > > >     x)
> > >
> > > Yes, that's non-conforming code.  Imagine all the cons cells in your
> > > quoted list being in read-only memory.
> > >
> > Don't hurt me but i don't understand it. In the Hyperspec i found:
> >
> > "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"
> >
> > But that doesn't hold for x since x is affected by the environment. I think that
> > '(1 2 3) is a list of constants but itself does not be constant.
> 
> In my mental model of the Lisp world, anything returned by QUOTE is in
> read-only space.  
Your mental model is right ;-)
I got some postings that explains that whole topic very good. Now it is clear
to me what's going on when i write '(anything). 
Thanks again to all who helped me to understand it.

Best regards
AHz
From: Barry Margolin
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <cQ5N8.11$Ps4.877@paloalto-snr2.gtei.net>
In article <···············@conquest.OCF.Berkeley.EDU>,
Thomas F. Burdick <···@conquest.OCF.Berkeley.EDU> wrote:
>In my mental model of the Lisp world, anything returned by QUOTE is in
>read-only space.

Except symbols, I hope.

(setq sym 'abc)
(setf (symbol-value sym) 1)

is allowed.

-- 
Barry Margolin, ······@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.
From: Thomas F. Burdick
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <xcvn0u266yx.fsf@conquest.OCF.Berkeley.EDU>
Barry Margolin <······@genuity.net> writes:

> In article <···············@conquest.OCF.Berkeley.EDU>,
> Thomas F. Burdick <···@conquest.OCF.Berkeley.EDU> wrote:
> >In my mental model of the Lisp world, anything returned by QUOTE is in
> >read-only space.
> 
> Except symbols, I hope.

No, but

> (setq sym 'abc)
> (setf (symbol-value sym) 1)
> 
> is allowed.

We only store the pointer to the package and the symbol-name in the
actual symbol object, so this isn't a problem (and yes, it does make
SYMBOL-VALUE slower, but it had to be for other reasons anyway).  This
has the *huge* advantage (for us) of making it so that C++ code won't
accidentally change a symbol's name.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Barry Margolin
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <O9oN8.5$%h2.175@paloalto-snr1.gtei.net>
In article <···············@conquest.OCF.Berkeley.EDU>,
Thomas F. Burdick <···@conquest.OCF.Berkeley.EDU> wrote:
>Barry Margolin <······@genuity.net> writes:
>
>> In article <···············@conquest.OCF.Berkeley.EDU>,
>> Thomas F. Burdick <···@conquest.OCF.Berkeley.EDU> wrote:
>> >In my mental model of the Lisp world, anything returned by QUOTE is in
>> >read-only space.
>> 
>> Except symbols, I hope.
>
>No, but
>
>> (setq sym 'abc)
>> (setf (symbol-value sym) 1)
>> 
>> is allowed.
>
>We only store the pointer to the package and the symbol-name in the
>actual symbol object, so this isn't a problem (and yes, it does make
>SYMBOL-VALUE slower, but it had to be for other reasons anyway).  This
>has the *huge* advantage (for us) of making it so that C++ code won't
>accidentally change a symbol's name.

But I think:

(setq sym 'abc)
(setf (symbol-package sym) ...)

is permitted.  The only part of a symbol that's not modifiable is the
symbol-name (this is true whether it was a literal or not).

-- 
Barry Margolin, ······@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.
From: Thomas F. Burdick
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <xcvr8jcne2o.fsf@conquest.OCF.Berkeley.EDU>
Barry Margolin <······@genuity.net> writes:

> But I think:
> 
> (setq sym 'abc)
> (setf (symbol-package sym) ...)
> 
> is permitted.  The only part of a symbol that's not modifiable is the
> symbol-name (this is true whether it was a literal or not).

No, SYMBOL-PACKAGE is a function, not an accessor, which is good for
me, as an implementor.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Barry Margolin
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <8j2O8.5$4w2.497@paloalto-snr2.gtei.net>
In article <···············@conquest.OCF.Berkeley.EDU>,
Thomas F. Burdick <···@conquest.OCF.Berkeley.EDU> wrote:
>Barry Margolin <······@genuity.net> writes:
>
>> But I think:
>> 
>> (setq sym 'abc)
>> (setf (symbol-package sym) ...)
>> 
>> is permitted.  The only part of a symbol that's not modifiable is the
>> symbol-name (this is true whether it was a literal or not).
>
>No, SYMBOL-PACKAGE is a function, not an accessor, which is good for
>me, as an implementor.

You're right.  But UNINTERN modifies the home package of a symbol if its
home package is the one it's being removed from, and IMPORT will set the
package of a symbol if it doesn't already have one.  So the package
attribute of a symbol is always changeable.

-- 
Barry Margolin, ······@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.
From: Geoff Summerhayes
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <ONOL8.194875$GG6.15809233@news3.calgary.shaw.ca>
"Ed L Cashin" <·······@uga.edu> wrote in message
······················@cs.uga.edu...
>
> Just to clarify, is the following code incorrect because it modifies a
> constant list?
>
>
>   (let ((x '(1 2 3)))
>     (setf (car x) 2)
>     x)
>

Yes, the code is incorrect. I'll alter it a bit so it shows
the modification.

: (defun foo()
    (let ((x '(1 2 3)))
      (incf (car x))))
FOO
: (foo)
2
: (foo)
3

The lisp's I've looked at do the above, but they are not required
to, FOO can return 2, blow up, cause the universe to end, anything
goes.

Do this instead,

: (defun bar()
    (let ((x (list 1 2 3)))
      (incf (car x))))
BAR
: (bar)
2
: (bar)
2

and save the universe, it looks better on the CV.

--
Geoff
From: Nils Goesche
Subject: Re: modify quoted list (was Re: weird function behavior)
Date: 
Message-ID: <lksn40usv0.fsf@pc022.bln.elmeg.de>
Ed L Cashin <·······@uga.edu> writes:

> is the following code incorrect because it modifies a constant list?
> 
>   (let ((x '(1 2 3)))
>     (setf (car x) 2)
>     x)

Yes, it's incorrect (undefined behaviour).

Regards,
-- 
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x42B32FC9
From: Erik Naggum
Subject: Re: weird function behavior
Date: 
Message-ID: <3230485142957966@naggum.net>
* Jacques Wainer <······@ic.unicamp.br>
| no where there is any indication that '(nil) is a constant.

  Yes, there is.  It is right there in the specification.  It also follows
  from other things you ought know about Common Lisp.

| The fact that the complier/evaluator considers that a constant to me is a
| bad design decision.

  A more irrelevant "argument" could probably not be constructed.

| In fact, I could accept that the compiler, with optimization set to a
| high level, would implement '(nil) as a constant but I would not expect
| the evaluator in clisp, to perform such optimization.

  This is how it works:

1 The Common Lisp reader is responsible for constructing the in-memory
  lists that make up the source program.  Thus, (quote (nil)) is the
  actual source code.

2 The quote special operator returns its unevaluated argument.  Thus, the
  (nil) is still the actual source code.

3 (elt x 0) refers to the car of one of the cons cells that make up the
  actual source code.

4 Changing the car of a cons cell that the actual source code is made up of
  _obviously_ affects the source code for the interpreter.

5 Common Lisp is based in the premise that the programmer knows what he is
  doing, so if the programmer does the above, it is because he means it.

6 Because compiled and interpreted code in Common Lisp are required to have
  identical semantics (meaning and behavior), the compiler has to preserve
  this property of quoted objects, i.e., objects produced by the Common
  Lisp reader.

7 This is not an optimization.  An optimization would be to make two
  _different_ '(nil) be the same.  This does not happen here.

| Before this event, I thought '(nil) to be operationally equivalent to
| (list nil), but just notationally more convenient.

  In Common Lisp, it is vitally important to understand when objects are
  constructed and when forms are evaluated.  There are four times that you
  should be aware of:

A read-time.  The Common Lisp reader builds the object when reading the
  source code and the compiler arranges for the object to be re-created
  when loading a compiled file.  Obtained with the special operator quote.
  The read macro #. also causes evaluation of expression to occur in the
  reader and the resulting value to be returned.

B load-time.  The Common Lisp loader builds the object either in order to
  preserve a read-time object creation, or as obtained with the special
  operator load-time-value.  (This used to be the read macro #, -- which I
  have a hard time understanding why was not just turned into a short-hand
  for load-time-value.)  Also controlled by eval-when :load-toplevel, or,
  more appropriately, excluding :load-toplevel from eval-when makes it not
  happen at load-time, because that is the default.

C compile-time.  The file compiler normally only reads source code and
  produces a binary file that arranges for the loader to produce the same
  effects as it would have if it loaded the source code, and does not
  evaluate the code it so compiles, unless eval-when :compile-toplevel is
  used to instruct the compiler to evaluate it.  Several macros do this.
  (I mention this and eval-when because you will run into a similar kind of
  problem sooner or later.  Then you will remember this, because you are
  annoyed by something you do not understand that bit you, now, too.)

D run-time.  The "normal" execution time that programmers want to control.
  At this time, it is much more important for you to understand that not
  everything happens at run-time than exactly what happens at run-time.

  I hope this helps.  My patience with people who think their ignorance
  gives them the right to denigrate design decisions they do not understand
  is _extremely_ short.  If you do not accept that the above is offered in
  the best interest of helping you understand something you previously did
  not, but come back with more negative and ignorant arroganceb about the
  design, you will only piss people off, and I will get seriously annoyed
  for having wasted my time on yet another unworthy person.  Most of us
  here would like to help people understand Common Lisp, but before you
  understand, you listen.  It is vital to successful learning that you do
  not jump to conclusions and accept that you do not understand or know
  something and do not have the right to even _have_ opinions on design
  decisions until you know what they are.  Most of the time, people who
  know little and speak much make fools of themselves and piss people off,
  and I have tended to express my strong desire to send these people to
  hell on the first shuttle out of here, but I shall make an attempt to
  delay that and ask you to think things through and try to avoid annoying
  people by believing that you know something you do not but which is a
  requirement for the opinions you think you have a right to have.  You do
  not have to agree with what I have told you, but you have to listen and
  study and make a visible effort to understand before you argue against
  it.  This is how things work.  In time, you will be the one giving this
  lecture.
-- 
  In a fight against something, the fight has value, victory has none.
  In a fight for something, the fight is a loss, victory merely relief.

  70 percent of American adults do not understand the scientific process.
From: Kaz Kylheku
Subject: Re: weird function behavior
Date: 
Message-ID: <slrnae90j0.i1f.kaz@localhost.localdomain>
On 15 May 2002 11:53:29 -0300, Jacques Wainer <······@ic.unicamp.br> wrote:
>Erik Naggum <····@naggum.net> writes:
>
>| * Jacques Wainer
>| | (defun prob()
>| |   (let ((x '(nil)))
>| |     (push 1 (elt x 0))))
>| 
>|   Where did you get the idea that you should use a quoted constant in your
>|   code to begin with?  I am actually seriously curious about this, because
>
>
>no where there is any indication that '(nil) is a constant.

Sure there is. '(nil) means (quote (nil)). (quote (nil)) is an expression which
has the object (nil) physically embedded in it.  Whenever this expression is
evaluated, the most natural thing is simply to regurgitate that embedded
object. I wouldn't consider this an optimization, just the lack of
pessimization.
From: lin8080
Subject: Re: weird function behavior
Date: 
Message-ID: <3CE6C41D.CB38DF4F@freenet.de>
Jacques Wainer schrieb:

> Lispers

> I student wrote the following code, whose behavior in clisp, below, I can't
> explain. What can be happening here, or is this a bug in clisp?

> [1]> (defun prob()
>   (let ((x '(nil)))
>     (push 1 (elt x 0))))
> PROB
> [2]> (prob)
> (1)
> [3]> (prob)
> (1 1)                           ;;<--------------- problem

...............

Hallo Jacques

I do defun 'probe' instead of your 'prob'. See line 8 in the
disassembly. The (trace) and (step) will not show more details on this.

[4]> (symbolp 'probe)
T
[5]> (disassemble 'probe)


Disassembly of function PROBE
(CONST 0) = ((1 1))
(CONST 1) = 0
(CONST 2) = 1
0 required arguments
0 optional arguments
No rest parameter
No keyword parameters
0     (CONST&PUSH 0)                      ; ((1 1))
1     (CONST&PUSH 1)                      ; 0
2     (CALLS2&PUSH 65)                    ; ELT
4     (CONST&PUSH 0)                      ; ((1 1))
5     (CONST&PUSH 1)                      ; 0
6     (CONST&PUSH 2)                      ; 1
7     (LOAD 3)
8     (CONS&PUSH)
9     (CALLS2 66)                         ; SYSTEM::%SETELT
11    (SKIP&RET 2)
#<COMPILED-CLOSURE PROBE>       ;;<--------------- compiled???

[6]> (lisp-implementation-version )
"2.28 (released 2002-03-03) (built on user [159.246.204.33])"

[7]> (exit)
Bye.

stefan