From: Shaul Markovitch
Subject: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <bdn1rfxkqq.fsf@cs.technion.ac.il>
I have noticed the following behavior using CMUCL.
Is this a legitimate behavior?  Do other compilers
use such "optimization" ?

File test12.lisp:

(defparameter *aaa* '(1 2 3 4 5 6 7 8 10))
(defparameter *bbb* '(1 2 3 4 5 6 7 8 10))

-------

* (load "test12.lisp")
; Loading #p"/home/shaulm/test12.lisp".
T
* *aaa*
(1 2 3 4 5 6 7 8 10)
* *bbb*
(1 2 3 4 5 6 7 8 10)
* (eql *aaa* *bbb*)
NIL
* (compile-file "test12" :load t)
Python version 1.0, VM version SPARCstation/Solaris 2 on 13 DEC 99 11:10:54 am.
Compiling: /home/shaulm/test12.lisp 13 DEC 99 11:08:29 am

Byte Compiling Top-Level Form: 

test12.sparcf written.
Compilation finished in 0:00:00.

; Loading #p"/home/shaulm/test12.sparcf".
#p"/home/shaulm/test12.sparcf"
NIL
NIL
* (eql *aaa* *bbb*)
T
* 
-- 
===============================================================
Shaul Markovitch, Computer Science Department
Technion - Israel Institute of Technology, Haifa 32000, Israel.       
Tel: 972-4-8294346  Fax:972-4-8221128  
http://www.cs.technion.ac.il/~shaulm/ ······@cs.technion.ac.il  

From: Fernando
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <vul95s81vdmjfckb296v4sl8rkqm4f4oeb@4ax.com>
On 13 Dec 1999 11:17:49 +0200, Shaul Markovitch
<······@cs.technion.ac.il> wrote:

>I have noticed the following behavior using CMUCL.
>Is this a legitimate behavior?  Do other compilers
>use such "optimization" ?

I think that Visual Basic does this sort of thing too, but I'm not
sure... :-?




//-----------------------------------------------
//	Fernando Rodriguez Romero
//
//	frr at mindless dot com
//------------------------------------------------
From: Barry Margolin
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <acb54.30$bB3.1280@burlma1-snr2>
In article <··································@4ax.com>,
Fernando  <·······@must.die> wrote:
>On 13 Dec 1999 11:17:49 +0200, Shaul Markovitch
><······@cs.technion.ac.il> wrote:
>
>>I have noticed the following behavior using CMUCL.
>>Is this a legitimate behavior?  Do other compilers
>>use such "optimization" ?
>
>I think that Visual Basic does this sort of thing too, but I'm not
>sure... :-?

Sharing of literal pools is a technique that compiler (and even assembler)
implementors have been using for decades.  In languages without pointers or
EQ, you can't usually tell that it's happening; in languages that have one
of these features, the language specification has to say whether it's
allowed, because you can detect it, as in the original poster's example.
Common Lisp and C both allow it; I'm not familiar enough with other
languages to know what their specs say about it.  Does VB even have one of
the features that would make coalescing apparent?

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, 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: Fernando
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <10qe5s4m4pcbm9crfsab66mjf39vs33vua@4ax.com>
On Mon, 13 Dec 1999 18:48:40 GMT, Barry Margolin
<······@bbnplanet.com> wrote:

>In article <··································@4ax.com>,
>Fernando  <·······@must.die> wrote:
>>On 13 Dec 1999 11:17:49 +0200, Shaul Markovitch
>><······@cs.technion.ac.il> wrote:
>>
>>>I have noticed the following behavior using CMUCL.
>>>Is this a legitimate behavior?  Do other compilers
>>>use such "optimization" ?
>>
>>I think that Visual Basic does this sort of thing too, but I'm not
>>sure... :-?
>
>Sharing of literal pools is a technique that compiler (and even assembler)
>implementors have been using for decades.  In languages without pointers or
>EQ, you can't usually tell that it's happening; in languages that have one
>of these features, the language specification has to say whether it's
>allowed, because you can detect it, as in the original poster's example.
>Common Lisp and C both allow it; I'm not familiar enough with other
>languages to know what their specs say about it.  Does VB even have one of
>the features that would make coalescing apparent?

There's a compiler setting that enables or disables variable aliasing,
but that's all.




//-----------------------------------------------
//	Fernando Rodriguez Romero
//
//	frr at mindless dot com
//------------------------------------------------
From: Christopher R. Barry
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <871z8qae2z.fsf@2xtreme.net>
Shaul Markovitch <······@cs.technion.ac.il> writes:

> I have noticed the following behavior using CMUCL.
> Is this a legitimate behavior?  Do other compilers
> use such "optimization" ?
> 
> File test12.lisp:
> 
> (defparameter *aaa* '(1 2 3 4 5 6 7 8 10))
> (defparameter *bbb* '(1 2 3 4 5 6 7 8 10))

You should be pleased that CMU CL does this "optimization", as it is a
good optimization to do. Any time you create quoted structure, the
consequences of modifying it are undefined. This allows the compiler
to put the structure in an unwritable/unmodifiable part of memory, so
that the GC has to do less work, for example.

Christopher
From: Tim Bradshaw
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <ey37liisggq.fsf@cley.com>
> You should be pleased that CMU CL does this "optimization", as it is a
> good optimization to do. Any time you create quoted structure, the
> consequences of modifying it are undefined. This allows the compiler
> to put the structure in an unwritable/unmodifiable part of memory, so
> that the GC has to do less work, for example.

That's just wrong.  It can obviously put the constants in readonly
memory even if it doesn't coalesce them.

--tim
From: Paul Wallich
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <pw-1312991654550001@166.84.250.180>
In article <···············@cley.com>, Tim Bradshaw <···@cley.com> wrote:

>> You should be pleased that CMU CL does this "optimization", as it is a
>> good optimization to do. Any time you create quoted structure, the
>> consequences of modifying it are undefined. This allows the compiler
>> to put the structure in an unwritable/unmodifiable part of memory, so
>> that the GC has to do less work, for example.
>
>That's just wrong.  It can obviously put the constants in readonly
>memory even if it doesn't coalesce them.

But if it doesn't coalesce them, then it's using at least twice as much
space as it needs to. 

Why would one want to run EQ on something like that, and where would
it matter? I'm trying to think of a way that this could be unsafe without
unlawful modification of the underlying quoted structure, and so far I can't.

paul
From: Tim Bradshaw
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <ey34sdmsahg.fsf@cley.com>
* Paul Wallich wrote:

> Why would one want to run EQ on something like that, and where would
> it matter? I'm trying to think of a way that this could be unsafe without
> unlawful modification of the underlying quoted structure, and so far I can't.

You might be relying on the fact that (EQ A B) is not true for two
constants A and B, only to find it becomes true when you compile &
load the file.  Of course that's a program bug not a system bug.

--tim
From: Paul Wallich
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <pw-1412991316400001@166.84.250.180>
In article <···············@cley.com>, Tim Bradshaw <···@cley.com> wrote:

>* Paul Wallich wrote:
>
>> Why would one want to run EQ on something like that, and where would
>> it matter? I'm trying to think of a way that this could be unsafe without
>> unlawful modification of the underlying quoted structure, and so far I can't.
>
>You might be relying on the fact that (EQ A B) is not true for two
>constants A and B, only to find it becomes true when you compile &
>load the file.  Of course that's a program bug not a system bug.

Aha, I think. If you mean by that "Any two constants A and B" i.e.
you're trying to determine whether these things are the same object
for purposes of some other transformation down the line. If a particular
A and B, then I still don't understand how you would want two things
that you had made to be visibly identical to fail an equality test -- almost
always it's the other way around, that you get bitten by those cases where
things can be EQUAL but not EQ...

paul
From: Barry Margolin
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <RFw54.18$GG5.1117@burlma1-snr2>
In article <···················@166.84.250.180>,
Paul Wallich <··@panix.com> wrote:
>In article <···············@cley.com>, Tim Bradshaw <···@cley.com> wrote:
>
>>* Paul Wallich wrote:
>>
>>> Why would one want to run EQ on something like that, and where would
>>> it matter? I'm trying to think of a way that this could be unsafe without
>>> unlawful modification of the underlying quoted structure, and so far I can't.
>>
>>You might be relying on the fact that (EQ A B) is not true for two
>>constants A and B, only to find it becomes true when you compile &
>>load the file.  Of course that's a program bug not a system bug.
>
>Aha, I think. If you mean by that "Any two constants A and B" i.e.
>you're trying to determine whether these things are the same object
>for purposes of some other transformation down the line. If a particular
>A and B, then I still don't understand how you would want two things
>that you had made to be visibly identical to fail an equality test -- almost
>always it's the other way around, that you get bitten by those cases where
>things can be EQUAL but not EQ...

Consider code like the following:

(let ((not-changed-flag '(nil)))
  (setf (struct-slot-a thing) not-changed-flag)
  (some-function thing)
  (when (eq (struct-slot-a thing) not-changed-flag)
    ;; do stuff that assumes SOME-FUNCTION didn't update the slot A
    ))

If, for some reason, SOME-FUNCTION (or something it calls) assigns '(nil)
to that slot, coalescing can cause the test to mistakenly thing that it
wasn't updated.

The warning about coalescing essentially means that you must write the
above code as:

(let ((not-changed-flag (list nil)))
  (setf (struct-slot-a thing) not-changed-flag)
  (some-function thing)
  (when (eq (struct-slot-a thing) not-changed-flag)
    ;; do stuff that assumes SOME-FUNCTION didn't update the slot A
    ))

By calling LIST, you're demanding that a fresh list be allocated.  If you
don't want a new flag to be created each time through that code, you can
do:

(defconstant +not-changed-flag+ (list nil))

and then use this.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, 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: Martin Simmons
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <01bf46ed$0f6cb840$35ee58c0@cutler>
Barry Margolin <······@bbnplanet.com> wrote in article
<·················@burlma1-snr2>... 
> The warning about coalescing essentially means that you must write the
> above code as:
> 
> (let ((not-changed-flag (list nil)))
>   (setf (struct-slot-a thing) not-changed-flag)
>   (some-function thing)
>   (when (eq (struct-slot-a thing) not-changed-flag)
>     ;; do stuff that assumes SOME-FUNCTION didn't update the slot A
>     ))
> 
> By calling LIST, you're demanding that a fresh list be allocated.  If you
> don't want a new flag to be created each time through that code, you can
> do:
> 
> (defconstant +not-changed-flag+ (list nil))
> 
> and then use this.

Is that guarateed to be non-coalescing?  The compiler is allowed to
evaluate the value-form at compile-time, so presumably it could be
coalesced when substituted (as per ANSI 3.2.2.3).

I think the only safe way is to use load-time-value

(let ((not-changed-flag (load-time-value (list nil))))
  ...)

-- 
Martin Simmons, Lisp Group, Harlequin Limited
······@harlequin.co.uk
From: Jeff Dalton
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <x2zov94pav.fsf@todday.aiai.ed.ac.uk>
"Martin Simmons" <······@harlequin.co.uk> writes:

> Barry Margolin <······@bbnplanet.com> wrote in article
> <·················@burlma1-snr2>... 
> > The warning about coalescing essentially means that you must write the
> > above code as:
> > 
> > (let ((not-changed-flag (list nil)))
> >   (setf (struct-slot-a thing) not-changed-flag)
> >   (some-function thing)
> >   (when (eq (struct-slot-a thing) not-changed-flag)
> >     ;; do stuff that assumes SOME-FUNCTION didn't update the slot A
> >     ))
> > 
> > By calling LIST, you're demanding that a fresh list be allocated.  If you
> > don't want a new flag to be created each time through that code, you can
> > do:
> > 
> > (defconstant +not-changed-flag+ (list nil))
> > 
> > and then use this.
> 
> Is that guarateed to be non-coalescing?  The compiler is allowed to
> evaluate the value-form at compile-time, so presumably it could be
> coalesced when substituted (as per ANSI 3.2.2.3).
> 
> I think the only safe way is to use load-time-value
> 
> (let ((not-changed-flag (load-time-value (list nil))))
>   ...)

Humm.  You may well be right.

I have another question about defconstant, though.  If a defconstant
is evaluated more than once, the results have to be EQL; and an
implementation is allowed to eval the form at both compile and
load time.  Doesn't that make it rather difficult to use defconstant
for any case where the value is a different (not EQL) object each
time?

-- j
From: Martin Simmons
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <01bf4b24$0cc7cdb0$35ee58c0@cutler>
Jeff Dalton <····@todday.aiai.ed.ac.uk> wrote in article
<··············@todday.aiai.ed.ac.uk>...

> I have another question about defconstant, though.  If a defconstant
> is evaluated more than once, the results have to be EQL; and an
> implementation is allowed to eval the form at both compile and
> load time.  Doesn't that make it rather difficult to use defconstant
> for any case where the value is a different (not EQL) object each
> time?

I think this is an environments issue. If you have a compiler which uses a
separate compilation environment, then the compile and load time values
won't interfere.  OTOH, if your compiler uses the global environment at
compile time, then "the consequences are undefined" but of course any given
compiler can define the consequences to do something sensible.
-- 
Martin Simmons, Lisp Group, Harlequin Limited
······@harlequin.co.uk
From: Jeff Dalton
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <x2ogbktixq.fsf@todday.aiai.ed.ac.uk>
"Martin Simmons" <······@harlequin.co.uk> writes:

> Jeff Dalton <····@todday.aiai.ed.ac.uk> wrote in article
> <··············@todday.aiai.ed.ac.uk>...
> 
> > I have another question about defconstant, though.  If a defconstant
> > is evaluated more than once, the results have to be EQL; and an
> > implementation is allowed to eval the form at both compile and
> > load time.  Doesn't that make it rather difficult to use defconstant
> > for any case where the value is a different (not EQL) object each
> > time?
> 
> I think this is an environments issue. If you have a compiler which uses a
> separate compilation environment, then the compile and load time values
> won't interfere.  OTOH, if your compiler uses the global environment at
> compile time, then "the consequences are undefined" but of course any given
> compiler can define the consequences to do something sensible.

The problem is that if I'm trying to write portable code, and trying
to avoid doing things where the consequences are undefined, then it
looks like I shouldn't try to DEFCONSTANT using an expression that
creates a new object each time it's evaluated.

A similar problem arises with DEFPACKAGE.

Anyway, now I'm wondering what people do about such things.  Ignore
the problem(s) on the assumption that good implementations will do
reasonable things?
From: Tim Bradshaw
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <ey366y2sckv.fsf@cley.com>
* I wrote:
>> You should be pleased that CMU CL does this "optimization", as it is a
>> good optimization to do. Any time you create quoted structure, the
>> consequences of modifying it are undefined. This allows the compiler
>> to put the structure in an unwritable/unmodifiable part of memory, so
>> that the GC has to do less work, for example.

> That's just wrong.  It can obviously put the constants in readonly
> memory even if it doesn't coalesce them.

Foo, I think I misread you -- I read `this' as `coalescing constants'
but I think you meant `making them readonly'.  Sorry.

--tim
From: Shaul Markovitch
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <bdln6yx9za.fsf@cs.technion.ac.il>
······@2xtreme.net (Christopher R. Barry) writes:

> Shaul Markovitch <······@cs.technion.ac.il> writes:
> 
> > I have noticed the following behavior using CMUCL.
> > Is this a legitimate behavior?  Do other compilers
> > use such "optimization" ?
> > 
> > File test12.lisp:
> > 
> > (defparameter *aaa* '(1 2 3 4 5 6 7 8 10))
> > (defparameter *bbb* '(1 2 3 4 5 6 7 8 10))
> 
> You should be pleased that CMU CL does this "optimization", as it is a
> good optimization to do. Any time you create quoted structure, the
> consequences of modifying it are undefined. This allows the compiler
> to put the structure in an unwritable/unmodifiable part of memory, so
> that the GC has to do less work, for example.
> 
> Christopher

Well, at least for me this behavior is counterintuitive.
The original problem that was the reason for the post 
occured with two counters that I defined:
(defvar *move-counter* '((:white 0)(:black 0)))
(defvar *time-counter* '((:white 0)(:black 0)))

I was surprised to find out that modifying one of them affected
the other.

I read each statement as: build a list with two elements (etc.).
If I would have wanted them to be EQ I would have stated:
(defvar *time-counter* *move-counter*)

If I would want to make them unwritable I would have stated:
(defconstant *move-counter* ....)

Eventually I had to replace it with:
(defvar *move-counter* (list (list :white 0)(list :black 0)))

Doesn't it look a bit weird to force me using such a notation?

Shaul



-- 
===============================================================
Shaul Markovitch, Computer Science Department
Technion - Israel Institute of Technology, Haifa 32000, Israel.       
Tel: 972-4-8294346  Fax:972-4-8221128  
http://www.cs.technion.ac.il/~shaulm/ ······@cs.technion.ac.il  
From: Barry Margolin
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <Ubz54.34$GG5.1002@burlma1-snr2>
In article <··············@cs.technion.ac.il>,
Shaul Markovitch  <······@cs.technion.ac.il> wrote:
>Well, at least for me this behavior is counterintuitive.
>The original problem that was the reason for the post 
>occured with two counters that I defined:
>(defvar *move-counter* '((:white 0)(:black 0)))
>(defvar *time-counter* '((:white 0)(:black 0)))
>
>I was surprised to find out that modifying one of them affected
>the other.

You're not allowed to modify them in the first place.

>I read each statement as: build a list with two elements (etc.).
>If I would have wanted them to be EQ I would have stated:
>(defvar *time-counter* *move-counter*)
>
>If I would want to make them unwritable I would have stated:
>(defconstant *move-counter* ....)

That's different; it's intended to prevent (setq *move-counter* ...).

>Eventually I had to replace it with:
>(defvar *move-counter* (list (list :white 0)(list :black 0)))
>
>Doesn't it look a bit weird to force me using such a notation?

We didn't want to come up with a new operator just to distinguish
modifiable from non-modifiable quoted data, and it seemed to us that most
literal data is not intended to be the starting point for modification.  As
a result, on occasion you have to resort to functions like that.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, 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: Tim Bradshaw
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <ey3hfhl87jh.fsf@cley.com>
* Shaul Markovitch wrote:
> Well, at least for me this behavior is counterintuitive.
> The original problem that was the reason for the post 
> occured with two counters that I defined:
> (defvar *move-counter* '((:white 0)(:black 0)))
> (defvar *time-counter* '((:white 0)(:black 0)))

> I was surprised to find out that modifying one of them affected
> the other.

Modifying quoted structure is illegal, so you can't safely modify even
one of them!

--tim
From: Coby Beck
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <945230935760@NewsSIEVE.cs.bonn.edu>
> Well, at least for me this behavior is counterintuitive.
> The original problem that was the reason for the post
> occured with two counters that I defined:
> (defvar *move-counter* '((:white 0)(:black 0)))
> (defvar *time-counter* '((:white 0)(:black 0)))
>
> I was surprised to find out that modifying one of them affected
> the other.
>

While i must admit i would not have anticipated that behavior either, on
reading the responses, it really does make sense.  You aren't doing here
what you really  mean to.  More appropriate would be something like:

(defstruct counter
     (white :type int)
     (black :type int))

(defvar *move-counter*  (make-counter :white 0 :black 0))
(defvar *time-counter*   (make-counter :white 0 :black 0))


> Eventually I had to replace it with:
> (defvar *move-counter* (list (list :white 0)(list :black 0)))
>
> Doesn't it look a bit weird to force me using such a notation?
>

On top of looking less "weird", using structures gives you alot of
convenient functionality reading and writing values etc.

Coby
From: Thomas A. Russ
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <ymi4sdm4ooj.fsf@sevak.isi.edu>
Shaul Markovitch <······@cs.technion.ac.il> writes:

> 
> I have noticed the following behavior using CMUCL.
> Is this a legitimate behavior?

Yes.  Since you are not supposed to modify constant lists, the language
sanctions creating only one list in your example.

>  Do other compilers
> use such "optimization" ?

Not sure.  It doesn't look like Allegro (Unix/Sparc) does it for lists.
MCL doesn't seem to either.  I tried setting optimization settings for
space to 3 and safety to 0, but it didn't help.

> File test12.lisp:
> 
> (defparameter *aaa* '(1 2 3 4 5 6 7 8 10))
> (defparameter *bbb* '(1 2 3 4 5 6 7 8 10))

-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Jeff Dalton
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <x21z8psckf.fsf@todday.aiai.ed.ac.uk>
···@sevak.isi.edu (Thomas A. Russ) writes:

> Shaul Markovitch <······@cs.technion.ac.il> writes:
> > 
> > I have noticed the following behavior using CMUCL.
> > Is this a legitimate behavior?
> 
> Yes.  Since you are not supposed to modify constant lists, the language
> sanctions creating only one list in your example.

No, that it's not conforming to modify them is not enough.  The
standard has to explicitly sanction coalescing (and it does).

One consquesce of coalescing is that you can't just say (as many want
to when teaching Lisp) that (eq 'a 'a) => t while (eq "a" "a") -> nil,
because in some circumstances the "two" "a"s might be coalesced.

-- j
From: Frode Vatvedt Fjeld
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <2h1z8rj9d8.fsf@dslab7.cs.uit.no>
Shaul Markovitch <······@cs.technion.ac.il> writes:

> Is this a legitimate behavior?

Yes. The HyperSpec, section 3.2.4.4, says:

    With the exception of symbols and packages, any two literal
    objects in code being processed by the file compiler may be
    coalesced if and only if they are similar; [...]

Where similarity is defined in section 3.2.3.2.2, but I guess you can
say in general that two objects that look the same in the source-code,
are "similar".

-- 
Frode Vatvedt Fjeld
From: Martin Simmons
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <01bf46ef$8d8a1c70$35ee58c0@cutler>
Does anyone have a view on how backquote is affected by coalescing?

E.g.

Can any of these be coalesced:
  `(10 20)
  `(,10 ,20)
  `(,(identity 10) ,(identity 20))?

Can the cdr of these be coalesced:
  `(,(print 10) 20 30)
  `(,(print 11) 20 30)?

The HyperSpec 2.4.6 uses the undefined term "side-effect behavior,"
implying that these can't be coalesced given the rules about `(x1 x2 x3 ...
xn) and `(x1 x2 x3 ... xn . atom), but I'll bet most backquote
implementions optimize some these cases to be constants.

-- 
Martin Simmons, Lisp Group, Harlequin Limited
······@harlequin.co.uk
From: Pekka P. Pirinen
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <ix66y0qmlh.fsf@gaspode.cam.harlequin.co.uk>
"Martin Simmons" <······@harlequin.co.uk> writes:
> Can the cdr of these be coalesced:
>   `(,(print 10) 20 30)
>   `(,(print 11) 20 30)?

Yes, I think so.  There's a blanket permission to reuse parts of the
form: "The constructed copy of the template might or might not share
list structure with the template itself", and the form is definitely a
constant (code must not be modified).

> The HyperSpec 2.4.6 uses the undefined term "side-effect behavior,"
> implying that these can't be coalesced given the rules about `(x1 x2 x3 ...
> xn) and `(x1 x2 x3 ... xn . atom), but I'll bet most backquote
> implementions optimize some these cases to be constants.

That sentence refers to the side-effect behavior of the backquote form
itself, so it's not relevant.  Furthermore, the example in this
section does use list constants in some of the possible expansions.
-- 
Pekka P. Pirinen, Adaptive Memory Management Group, Harlequin Limited
Hell is other posters.
  - Nancy Lebovitz  (nancyL_universe.digex.net)
From: ArolAmbler
Subject: Re: Should compilers be allowed to save space by "aliasing?"
Date: 
Message-ID: <20000117021417.28107.00000333@nso-fk.aol.com>
CERTAINLY!  ABOSOULTELY!  

Its the whole point of the "similar as a constant" stuff.

AND, in the presence of good compilers, especially with defmethod,
there will be "lots" of cases of "similar as a constant" that arise.

What about when a "compile-time" evaluation results in a bignum, and
the same bignum happens to be in many other places - who wants
62 copies of a tenthousand digit number in their code image, even
if they are all "read-only": you mess up the workin set of the computer!

As to the "obvious":  anytime you use a defvar, its value should either
be "unbound", or "freshly constructed", or you are just BEGGING for
trouble.  Any setf or setq in the world is "invited" to alter the constant.

As to the initial post, don't convert
(defvar *foo* '((foo 1) (fum 2)))
to
(defvar *foo* (list (list 'foo 1) (list 'fum 2)))
but to
(defvar *foo* (copy-tree '((foo 1) (fum 2))) )

(Theoretically, the second case is still "wrong", in that, 1 and 2
"COULD" be inplemented in a way that "might" cause them to
cause a run-time "attempt to alter read-only memory" with
a  simple 
    (incf (second (first *foo*)))
--  but, I'll admit, it would be a  RARE compiler.

However: the point is:  EVEN as simple a construct as

(defvar *large-number* 100000000)
or
(defvar *default-error-message-format*
    "You have a syntax error on line ~D of file ~A."
)


is ASKING for trouble.   

Much better:

(defvar *large-number* (+ 100000000))
and
(defvar *default-error-message-format*
      (copy-sequence ....)
)

---
But: the point is a good one.   Probably, wise compiler
writers, rather than emitting a warning message about
a top-level defvar with a constant initization, should instead
make defvar always (at least when at top-level, and compiling)
wrap any initialization value with a suitable "copy" function,
so that compiled and interpreted "eq-ness" are identical, 
EVEN when the user has done something of doubtful validity.
IDEALLY, a warning should also be emitted.

Particularly with CLOS, where specialization can be done 
on (eql xxx), some REAL surprises could occur if the intial
values of variables (or any subpart of them), if there are
any objects that are not eq when interpreted, suddenly become
eq, and therefore eql, when compiled, so that DIFFERENT 
methods could be called.   Most likely to result in a long debugging
session, if nothing worse (lawsuits, deaths, etc.)

And, the code just as you THOUGHT you had it nailed, and you
try to debug (usually at least partially interpretively), the problem
"disappears" -- "Wow - it MUST be a compiler bug!"   Bad scene.

I'd rather rephase the question, from "should compilers be allowed
to ..."  TO

"Do compiler writers who write buggy compilers and the corporations
who sell them be allowed to avoid a responsibility for the consequences when
the bugs result in major monetary losses, or losses in human life, or similar
things?"

After all, although I'm not a professional sidewalk snow-shoveller, I do
bear a legal responsibility if my mailman slips on the ice or snow on
my steps.

And, since programs ARE possible to be made perfect (even though the vast
majority of folklore says otherwise), any bugs are ALWAYS the result of either
the use of inadequate construction techniques, inadequate testing techniques,
inadequate specifications, inadequate education, inadequate time to do the job
right, or some other "cost-cutting" corner,
(insert sarcastic tone here)
 the "saved" money can "easily" pay for the
"obviously" rare case that a bug "matters".
(end sarcasm).

EITHER: 
A,  its actually not too expensive and hard to make perfect
softare (including compilers), and so they CAN be "guaranteed" to
work,
OR
B. Its "too hard(expensive, takes too long, etc.)" to write "perfect code".

BUT: If 2 is the case, then, why is it "easier (cheaper, quicker, etc.)"
to FIX the bugs AFTER the customers have already found them,
even though the 2 of the 5 developers are no longer with the company?


No - I'm not NUTS.  I've written several compilers, and been working on putting
my fair share of bugs into the world. 

But:
  1. I started in 1965.
  2. I started with lisp in 1969.
  3. I was into operating systems, machine architecture design, and
      language implementations before 1972.
   ....
   AND, in 1992 I found a way to build a program (a non-trivial
   language system, multi-threaded, with about 600 productions
   in the BNF grammar) to avoid almost every kind of bug I knew
  about.   Result: there was NEVER, ONCE, in the product's
   lifetime in the field, even ONE bug reported (but many enhancement
   requests).

    And, since then, I've found "improvements", that mean it CAN be done,
    and be EASILY taught, to virtually all programmers.   So - I'm seriously
    thinking of building a "programmer's  work bench" that REALLY is one...
    with the property that any program built using it is GUARANTEED to
    be bug free....


    Arol Ambler