From: Bruce R. Miller
Subject: Re: Constants in code (Ex- Virtues of Lisp syntax)
Date: 
Message-ID: <2863191137@ARTEMIS.cam.nist.gov>
In article <···················@Cygnus.COM>, David Vinayak Wallace writes: 
>    Date: 21 Sep 90 22:09:56 GMT
>    From: ······@GEM.cam.nist.gov (Bruce R. Miller)
>     Larry Masinter wrote:
>    >   (let ((var '(a b c)))
>    >       ...
>    >       (nconc var value))
> ...
>    In any  case,  one  could  imagine  a  perfectly legitimate interpretter
>    consing the list fresh  every time, giving  a 3rd behavior.   Before you
>    groan, consider that this might in fact be the most consistent behavior!
>    The (QUOTE (A B C)) form is (conceptually, at least) evaluated each time
>    the function is called!  Should (QUOTE (A B C)) sometimes 
>    return (A B C FOO)?
> 
> The interpretation of either case is straightforward.
> 
> Quote returns the object it was handed.  It doesn't try to guess "what
> you meant."  After all, the code isn't text; quote just has a pointer
> to the car of the list you handed it!
> 
I'm a little confused about what you're saying. In the simplest case,
READ consed up the list, and QUOTE just returns its arg.
Clearly if you repeatedly INTERPRETED the above form, you get the same
result each time.  (but perhaps not within a defun which may or may
not digest the form!) Compilation makes it a bit less clear; READ is no
longer involved. What pointer are we handing it?

If you WANT the permanent change then you should presumably write
(let ((var '(a b c)))
   (defun foo (..)
     .. (nconc var value)))	
to make clear the extent of var.

> I would be unhappy if quote performed computation each time you used 
> it!  A very common idiom is to pass a quoted, uninterned symbol around
> as a marker in some  structure.  (I used to  use '(())).  This is  the
> only way  I  can  get  a  token  I  guarantee won't appear in my input
> stream!
>

So would I!!!!  I dont quite follow your example, but I'm certainly  not
suggesting that quote should creates a new list -- nor even that the  (a
b c) should be consed anew each time.  Indeed, I expect the quote should
`disappear' upon compilation. I  just wanted to  say that the  EFFECT of
that approach MAY be the most appropriate behavior.

> Anyway, the capability to side-effect constants in storage was not
> removed for taste reasons, but efficiency; it permits me as a lisp
> implementor to place code into read-only storage (and possibly share
> it among processes).

Ah, if it's in read-only storage then you can NOT modify it, no?

BTW; Tim Moore, in another posting pointed out that this is considered
`illegal' although he didn't say if CLtL specified whether an error is
signalled or whether it is simply `undefined'.

bruce

From: Tim Moore
Subject: Re: Constants in code (Ex- Virtues of Lisp syntax)
Date: 
Message-ID: <1990Sep24.162735.13243@hellgate.utah.edu>
In article <··········@ARTEMIS.cam.nist.gov> ······@cam.nist.gov (Bruce R. Miller) writes:
>
>In article <···················@Cygnus.COM>, David Vinayak Wallace writes: 
>>    Date: 21 Sep 90 22:09:56 GMT
>>    From: ······@GEM.cam.nist.gov (Bruce R. Miller)
>>     Larry Masinter wrote:
>>    >   (let ((var '(a b c)))
>>    >       ...
>>    >       (nconc var value))
>> ...
>> Quote returns the object it was handed.  It doesn't try to guess "what
>> you meant."  After all, the code isn't text; quote just has a pointer
>> to the car of the list you handed it!
>> 
>I'm a little confused about what you're saying. In the simplest case,
>READ consed up the list, and QUOTE just returns its arg.
>Clearly if you repeatedly INTERPRETED the above form, you get the same
>result each time. (but perhaps not within a defun which may or may
>not digest the form!)

Regardless of any processing done by defun, the form is read only
once. It is true that the cons cell that is the value of var is
the same from invocation to invocation. However, the intention is that
the last element of the list whose head is that cons cell will be
changed each time through the code. So the result, (say, the return
value of nconc) is different each time.

>If you WANT the permanent change then you should presumably write
>(let ((var '(a b c)))
>   (defun foo (..)
>     .. (nconc var value)))	
>to make clear the extent of var.

This implies that foo is a closure. The previous code is an idiom that
dates from Lisps without closures. You're still trying to modify a
quoted constant here. If you have closures you might as well do

(let ((var '(c b a)))
  (defun foo (...)
    (push value var)))

>> Anyway, the capability to side-effect constants in storage was not
>> removed for taste reasons, but efficiency; it permits me as a lisp
>> implementor to place code into read-only storage (and possibly share
>> it among processes).
>
>Ah, if it's in read-only storage then you can NOT modify it, no?

If you want to modify it, don't quote it.

>
>BTW; Tim Moore, in another posting pointed out that this is considered
>`illegal' although he didn't say if CLtL specified whether an error is
>signalled or whether it is simply `undefined'.

In the terminology of CLtL, "it is an error". This means that valid
Common Lisp programs can't do it, but if it's done the results are
undefined and an error need not be signalled.

>
>bruce
Tim Moore                    ·····@cs.utah.edu {bellcore,hplabs}!utah-cs!moore
"Ah, youth. Ah, statute of limitations."
		-John Waters
From: Jeff Dalton
Subject: Re: Constants in code (Ex- Virtues of Lisp syntax)
Date: 
Message-ID: <3448@skye.ed.ac.uk>
I couldn't quite make out who wrote the stuff quoted below, so I
decided to avoid the risk of misattribution by not attributing it
to anyone.

>> I would be unhappy if quote performed computation each time you used 
>> it!  A very common idiom is to pass a quoted, uninterned symbol around
>> as a marker in some  structure.  (I used to  use '(())).  This is  the
>> only way  I  can  get  a  token  I  guarantee won't appear in my input
>> stream!

I always call LIST or CONS to get a unique object, rather than rely on
anything that involves QUOTE, although some people have pointed out
that, if you want an object that cannot appear in a stream, the stream
itself will do (unless, thanks to #., the stream is held in a global
variable).  That is, you do something like:

   (with-open-stream (s ...)
     (do ((input (read s nil s) (read s nil s)))
         ((eq input s))
       (process input)))

-- Jeff