From: Amanda Stent
Subject: multiple copies of a CLOS object?
Date: 
Message-ID: <9jsjl7$fb6$1@hydra.cs.rochester.edu>
Is there a CLOS function for copying a CLOS object so that you end up with
two clones that are thereafter independent?

Thanks in advance.

From: Thomas A. Russ
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <ymiitgeujad.fsf@sevak.isi.edu>
Amanda Stent <·····@cs.rochester.edu> writes:

> 
> Is there a CLOS function for copying a CLOS object so that you end up with
> two clones that are thereafter independent?

Short answer:
No.

Longer answer:
Partly because it isn't clear what you mean by "thereafter
independent".  If the filler of a slot were an object, should that
object be recursively copied?  If so, then you get into problems with
circular object graphs.  If not, then a change to the internal state of
that filler would be reflected in the internal state of the filler of
the copy as well.  That might not be independent enough for you.  What
about if two slots point to the same filler?  Should they be copied?

Basically the problem is that the meaning of a copy requires knowledge
of the semantics of the data structure which are not captured in the
programming language.  It is thus nearly impossible to get right in
general.

The above is a concise summary of some of the arguments in the Lisp
community about why there is no such utility.  Kent Pitman has a more
detailed and well-reasoned (published) response to this issue.

******

Notwithstanding those arguments, an shallow instance copy would IMHO be
useful in enough simple cases to be worth adding to the standard....

-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Erik Naggum
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <3205256646517069@naggum.net>
* Amanda Stent <·····@cs.rochester.edu>
> Is there a CLOS function for copying a CLOS object so that you end up
> with two clones that are thereafter independent?

  No.  There is no way to define "copy" such that this can be done without
  serious intervention from the creator of the class.  E.g., if you have a
  symbol as the value of a slot, do you want to copy the symbol, and if you
  copy the symbol, do you want to copy the package?  If you do copy the
  package, do you want to copy _all_ its symbols?  Obviously, this leads to
  a copy of the entire Lisp world in no time (in practice it will much more
  time).  You are better off with the Unix system call "fork".  This is not
  normally what people think of when they want a copy of an object, however.

  If you believe that a shallow copy is the right default choice in sharp
  contrast to the very deep copy described above, consider an object that
  points to itself with one of its slots.  A shallow copy would not make
  the "clones" independent at all, they would be like Siamese twins, and
  you would likely wreak havoc if you believed they _were_ independent.

  In the Common Lisp world, we do not generally believe in functions that
  work "most of the time", but look for the border conditions that make it
  necessary to point out when it works and when it does not.  A general
  "copy constructor" is not well-defined enough to make this possible.

  Besides, there is so much going on in CLOS objects that even if you
  succeed in making a copy, you may have broken many significant other
  things that depended on object identity in ways the object may not know
  about.  See also the desire to compare two objects for anything other
  than object identity.  Those who say it can be done are simply wrong,
  because the information necessary to accomplish this seemingly simple
  task is not specified by the language.  It is in the _intent_ of the
  programmer, not the _expression_ of that intent.  Until we find a way to
  write down the intent directly, we can only deal with expressions of
  intent in our programming languages.

  In other words, the PhD-level answer is "create a language such that it
  can automatically construct a copy constructor that always does the right
  thing".  It is simpler to write the code for your own copying function.

#:Erik
-- 
  There is nothing in this message that under normal circumstances should
  cause Barry Margolin to announce his moral superiority over others, but
  one never knows how he needs to behave to maintain his belief in it.
From: Kent M Pitman
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <sfw1yn1r14p.fsf@world.std.com>
Amanda Stent <·····@cs.rochester.edu> writes:

> Is there a CLOS function for copying a CLOS object so that you end up with
> two clones that are thereafter independent?

For an explanation of why this is perhaps a harder problem than you may
think, see:
               http://world.std.com/~pitman/PS/EQUAL.html
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <8766cbaqdv.fsf@frown.here>
Fernando <···@wanadoo.es> writes:

> On 27 Jul 2001 16:41:11 -0400, Amanda Stent <·····@cs.rochester.edu> wrote:
> 
> >Is there a CLOS function for copying a CLOS object so that you end up with
> >two clones that are thereafter independent?
> 
> Not really, there's no automagic way of making deep copies of objects (in CLOS
> or any other OOP).
Is it really? Now in Eiffel I wrote deep_copy and got it. So probably
I'm missing something.



> 
> PS  BTW, everytime I thought I had the need for a _deep_ copy, I was wrong...
> If you're coming from a C++ background, remember that in Lisp (because of the
> GC) copying objects isn't necesary to make sure they are 'deleted' at he right
> time: an object doesn0t need to 'own' another one in order to delete
>it.
I have a somewhat larger Eiffel program and in it there is exactly
one deep_copy. I tried to get away without it but
unsuccessfull. I do think that a deep_copy is a very useful thing, as
are other facilites. Too often used it could probably indicate a
"structural" problem.

Regards
Friedrich
From: Tim Bradshaw
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <ey34rrux6ae.fsf@cley.com>
* Friedrich Dominicus wrote:
> Fernando <···@wanadoo.es> writes:

>> Not really, there's no automagic way of making deep copies of objects (in CLOS
>> or any other OOP).
> Is it really? Now in Eiffel I wrote deep_copy and got it. So probably
> I'm missing something.

Would your automatic deep copier deal correctly with this class:

(defclass fifo ()
  ((queue :initform '())
   (queue-tail :initform nil)))

(hint: in order to work, the copier has to ensure that if the QUEUE
slot is non-NIL then QUEUE-TAIL must be the last cons in QUEUE).

--tim
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <87d76ialbe.fsf@frown.here>
Tim Bradshaw <···@cley.com> writes:

> * Friedrich Dominicus wrote:
> > Fernando <···@wanadoo.es> writes:
> 
> >> Not really, there's no automagic way of making deep copies of
> objects (in CLOS
> >> or any other OOP).
> > Is it really? Now in Eiffel I wrote deep_copy and got it. So probably
> > I'm missing something.
> 
> Would your automatic deep copier deal correctly with this class:
> 
> (defclass fifo ()
>   ((queue :initform '())
>    (queue-tail :initform nil)))
> 
> (hint: in order to work, the copier has to ensure that if the QUEUE
> slot is non-NIL then QUEUE-TAIL must be the last cons in QUEUE).
hint. in Eiffel one specfied the characteristics either by Pre or
Postconditions or invariants. You class would probably look like this
in Eiffel

class FIFO[G]

creation
   make ..

feature
   queue : LIST [G];
   tail : G


invariant
tail_constraint: tail = queue.item(count);

or the like

If I do a deep-clone all assertions have to be fullfilled for the
constraints too.

So If I have a
a : FIFO[FOO];
b : FIFO[FOO];

I got a full copy with
b := a.deep_clone;

So I can be sure that the constraint tail = queue.item(count) will
hold.

BTW I do think that one of the next addings to Common Lisp should be
features for Design by Contract. I know that there is a package for
it, anyway that should be standardized. Tools should be used to extrac
a) the documentation (as it is done nicely in Common Lisp)
b) the contracts (which are lacking in Common Lisp)


Regards
Friedrich
From: Kent M Pitman
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <sfw66ca67yo.fsf@world.std.com>
Friedrich Dominicus <·····@q-software-solutions.com> writes:

> Tim Bradshaw <···@cley.com> writes:
> 
> > * Friedrich Dominicus wrote:
> > > Fernando <···@wanadoo.es> writes:
> > 
> > >> Not really, there's no automagic way of making deep copies of
> > objects (in CLOS
> > >> or any other OOP).
> > > Is it really? Now in Eiffel I wrote deep_copy and got it. So probably
> > > I'm missing something.
> > 
> > Would your automatic deep copier deal correctly with this class:
> > 
> > (defclass fifo ()
> >   ((queue :initform '())
> >    (queue-tail :initform nil)))
> > 
> > (hint: in order to work, the copier has to ensure that if the QUEUE
> > slot is non-NIL then QUEUE-TAIL must be the last cons in QUEUE).
> hint. in Eiffel one specfied the characteristics either by Pre or
> Postconditions or invariants. You class would probably look like this
> in Eiffel
> 
> class FIFO[G]
> 
> creation
>    make ..
> 
> feature
>    queue : LIST [G];
>    tail : G
> 
> 
> invariant
> tail_constraint: tail = queue.item(count);
> 
> or the like
> 
> If I do a deep-clone all assertions have to be fullfilled for the
> constraints too.
> 
> So If I have a
> a : FIFO[FOO];
> b : FIFO[FOO];
> 
> I got a full copy with
> b := a.deep_clone;
> 
> So I can be sure that the constraint tail = queue.item(count) will
> hold.

Doesn't this rely on your constraint language to represent all possible
intentional truths about the real world which need to be held invariant,
rather than merely all truths you have programmed.

This seems to place an unreasonable burden on the programmer of the
initial application.  Suppose the queue is the queue to enter Buckingham
palace and cannot be cloned?  Suppose it's one of several (but not an infinite
number of) queues that can be cloned in a finite-world model?  Suppose there
is a complex inter-relationship where there can be only one of someting per
n of something else but when something is cloned, the matter around it 
rearranges to keep things in balance?  How much of this does the person
who doesn't realize "clone" will be done have to preprogram to have a correct
library and how much do they do as a burden of writing clone?  I claim that
correct code should explicitly offer a method to clone something if it wants
to and the absence of something that says you've done it correctly should
mean you don't know how; making the default the other way around leads
you with a big burden of proof.  Further, I also claim that a correct copying
requires knowing the purpose for which you are copying.  The same object
has multiple (even multiple "deep") copy meanings--do I descend leaves?
their leaves?  The answer comes from the reason for the copy.

> BTW I do think that one of the next addings to Common Lisp should be
> features for Design by Contract.

Fine area for research.  Things are best not added to the language
unless they are stable, commonly implemented (by multiple vendors),
etc.

> I know that there is a package for
> it, anyway that should be standardized. Tools should be used to extrac
> a) the documentation (as it is done nicely in Common Lisp)
> b) the contracts (which are lacking in Common Lisp)

Nothing in the language keeps you from building an embedded language
that does this, and then showing the wonders of all the programs that 
can be built on it.

I hear so often that people want to extend the language.  For the last 6
months I've been doing tons of programming on my own based on my own notions
of extension but not waiting for the language.  I just made my own base 
package and shadowed things as I liked and added symbols I wanted and went
to town.  It's really fun and requires no one to bless what I've done.
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <874rru605o.fsf@frown.here>
Kent M Pitman <······@world.std.com> writes:

> 
> This seems to place an unreasonable burden on the programmer of the
> initial application.
I disagree. It maybe a burden but it's a very helpful tool. And in
fact you can sit down and "first" write down the contracts and make
you implementation adhere to thos contracts. This is a really good
thing.


>Suppose the queue is the queue to enter Buckingham
> palace and cannot be cloned?

Do you think that is a realistic example for QUEUE? If you want to
disallow copying have the option to redefine the clone methods. I
would discourage doing that, and in fact I never have seen such a
thing but in inteface classes  (c structures!)

> I claim that
> correct code should explicitly offer a method to clone something if it wants
> to and the absence of something that says you've done it correctly should
> mean you don't know how; making the default the other way around leads
> you with a big burden of proof.  Further, I also claim that a correct copying
> requires knowing the purpose for which you are copying.  The same object
> has multiple (even multiple "deep") copy meanings--do I descend leaves?
> their leaves?  The answer comes from the reason for the copy.
I do not understand what you want to say with that.

> 
> > BTW I do think that one of the next addings to Common Lisp should be
> > features for Design by Contract.
> 
> Fine area for research.  Things are best not added to the language
> unless they are stable, commonly implemented (by multiple vendors),
> etc.
It is implemented in all Eiffel compilers it is implemented in Sather
and there are libraries doing that for (duck) Java and C++. As
mentioned before one has done it for Common Lisp too.


> Nothing in the language keeps you from building an embedded language
> that does this, and then showing the wonders of all the programs that 
> can be built on it.
Now, nothing prevents me from doing it, but it's not standard. It is
neverthelsss usefull.

Regards
Friedrich
From: Tim Bradshaw
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <ey3zo9mvfdg.fsf@cley.com>
* Friedrich Dominicus wrote:

> So I can be sure that the constraint tail = queue.item(count) will
> hold.

This would probably work for the class I gave, but it seems to be a
non-solution in general.  Firstly it requires you to describe,
up-front, all the things that must be true about the objects;
secondly, and worse, at least in theory, it requires the system to be
able to deduce from a constraint an algorithm for ensuring the
constraint is true.  This is a hard problem!

--tim
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <87zo9m4lgf.fsf@frown.here>
Tim Bradshaw <···@cley.com> writes:

> * Friedrich Dominicus wrote:
> 
> > So I can be sure that the constraint tail = queue.item(count) will
> > hold.
> 
> This would probably work for the class I gave, but it seems to be a
> non-solution in general.
Now it works in general for Eiffel. 

> Firstly it requires you to describe,
> up-front, all the things that must be true about the objects;
> secondly, and worse, at least in theory, it requires the system to be
> able to deduce from a constraint an algorithm for ensuring the
> constraint is true.  This is a hard problem!
Why? You as a programmer have to assure that constraints are
obeyed. If you mess it up an Exception is raised. The constraint you
were mentoning can be handeled that way and it's specified and it's
computer provable. So I can't see where the problem is whith
specifying such things if you know them.


Regard
Friedrich
From: Tim Bradshaw
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <ey3u1zuv64h.fsf@cley.com>
* Friedrich Dominicus wrote:
> Why? You as a programmer have to assure that constraints are
> obeyed. If you mess it up an Exception is raised. The constraint you
> were mentoning can be handeled that way and it's specified and it's
> computer provable. So I can't see where the problem is whith
> specifying such things if you know them.

Yes, I have to ensure the constraints are obeyed.  To do that I may
have to write substantial, non-trivial code.  Knowing the constraint
is *not* the same thing as being able to ensure it is
satisfied mechanically.

In one limit case the constraint can be an arbitrary predicate on the
object: your proposed deep-copy function now has to somehow
automagically ensure that the copy satisfies this same predicate.  In
finite time, too.

In another limit case the constraint may be that the object
corresponds with various real-world objects: copying it would
logically require copying them too.  That may be hard.

Obviously there are useful cases where these hairy constraints are not
needed, and your system will work there.  This is OK as far as it
goes, but it is *not* a general deep-copy: there *is no useful notion*
of a general deep copy.  This is what we are trying to say.

This is number 2 in Bradshaw's list of computer science cretinisms:
using abstractions which don't exist.

--tim
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <878zh64d56.fsf@frown.here>
Tim Bradshaw <···@cley.com> writes:

> 
> Yes, I have to ensure the constraints are obeyed.  To do that I may
> have to write substantial, non-trivial code.  Knowing the constraint
> is *not* the same thing as being able to ensure it is
> satisfied mechanically.

Now that is true, but for that the constraints are "build-in" into
Eiffel, please don't forget that we are talking about a language where
"the world" is "more or less static". 
> 
> In one limit case the constraint can be an arbitrary predicate on the
> object: your proposed deep-copy function now has to somehow
> automagically ensure that the copy satisfies this same predicate.  In
> finite time, too.
Now if Eiffel if you do an deep_copy all elements are recursively
copied. So if you have a last element in a and make a deep_copy you'll
have a last element in b and the complete list too and if you the
invariant is checked it used the copied list and the last element to
"check" if the constraint is true.

> 
> Obviously there are useful cases where these hairy constraints are not
> needed, and your system will work there.  This is OK as far as it
> goes, but it is *not* a general deep-copy: there *is no useful notion*
> of a general deep copy.  This is what we are trying to say.

I do think that a deep copy makes sense in Eiffel. As I told before
it's quite a static language. I do not know how it could work in a
dynamic language like Common Lisp though.

Regards
Friedrich
From: Bernhard Pfahringer
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <9k7o1e$2tu$1@hummel.cs.waikato.ac.nz>
In article <···············@cley.com>, Tim Bradshaw  <···@cley.com> wrote:
>
>Obviously there are useful cases where these hairy constraints are not
>needed, and your system will work there.  This is OK as far as it
>goes, but it is *not* a general deep-copy: there *is no useful notion*
>of a general deep copy.  This is what we are trying to say.
>
>This is number 2 in Bradshaw's list of computer science cretinisms:
>using abstractions which don't exist.
>

Well, first I've to admit to being a computer scientist :-)

I beg to differ: there is a *useful* notion of deep copy!
But probably it should be called a "full copy".
It is a complete copy of all objects involved with proper
conservation of all sharing, i.e. each object is copied exactly
once. E.g. this is what serialization does in Java (*).

Of course this is not what you would be using for copying
your queue data structure, if you just want to copy the
"container". For that purpose you'd be using "clone", I suppose.
And if you'd need anything in between (DEEP-ENOUGH-COPY), you'd
have to roll your own.

So my claim is that for most abstract data types you will find two
protocols sufficient:

 - full/deep copy (= serialization)
 - shallow copy/cloning: the minimal reasonable amout of copying

These two are at either end of a spectrum of "different-depth"
copiers. But mostly you'll only need those two.
Therefore it is reasonable for a language to support these explicitly.

Bernhard

(*) In principle, at least. I know about "transient", but lets not
turn this into a Java discusssion.
-- 
---------------------------------------------------------------------
Bernhard Pfahringer, Dept. of Computer Science, University of Waikato
http://www.cs.waikato.ac.nz/~bernhard                  +64 7 838 4041
---------------------------------------------------------------------
From: Ian Wild
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <3B67D835.7C3EAD51@cfmu.eurocontrol.int>
Bernhard Pfahringer wrote:
> 
> ... there is a *useful* notion of deep copy!
> But probably it should be called a "full copy".
> It is a complete copy of all objects involved with proper
> conservation of all sharing, i.e. each object is copied exactly
> once. E.g. this is what serialization does in Java (*).
> 

But have you read the explanation of why 'serializable' is
NOT the default case in Java?  As it says in
http://java.sun.com/products/jdk/1.2/docs/guide/rmi/faq.html
"it is far too easy to design a class that falls apart under
serialization and re-construction."
From: Bernhard Pfahringer
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <9ka42q$a5$1@hummel.cs.waikato.ac.nz>
In article <·················@cfmu.eurocontrol.int>,
Ian Wild  <···@cfmu.eurocontrol.int> wrote:
>Bernhard Pfahringer wrote:
>> 
>> ... there is a *useful* notion of deep copy!
>> But probably it should be called a "full copy".
>> It is a complete copy of all objects involved with proper
>> conservation of all sharing, i.e. each object is copied exactly
>> once. E.g. this is what serialization does in Java (*).
>> 
>
>But have you read the explanation of why 'serializable' is
>NOT the default case in Java?  As it says in
>http://java.sun.com/products/jdk/1.2/docs/guide/rmi/faq.html
>"it is far too easy to design a class that falls apart under
>serialization and re-construction."

Yes, but all the examples mentioned are problems due to 
shifting in time or space, i.e. reconstructing in a different
runtime environment. The copy we are discussing is assumed to
happen inside the same (Common Lisp) runtime.

Bernhard
-- 
---------------------------------------------------------------------
Bernhard Pfahringer, Dept. of Computer Science, University of Waikato
http://www.cs.waikato.ac.nz/~bernhard                  +64 7 838 4041
---------------------------------------------------------------------
From: Ian Wild
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <3B690C83.9DE4BCAC@cfmu.eurocontrol.int>
Bernhard Pfahringer wrote:
> 
> In article <·················@cfmu.eurocontrol.int>,
> Ian Wild  <···@cfmu.eurocontrol.int> wrote:
> >Bernhard Pfahringer wrote:
> >>
> >> ... there is a *useful* notion of deep copy!
> >> But probably it should be called a "full copy".
> >> It is a complete copy of all objects involved with proper
> >> conservation of all sharing, i.e. each object is copied exactly
> >> once. E.g. this is what serialization does in Java (*).
> >>
> >
> >But have you read the explanation of why 'serializable' is
> >NOT the default case in Java?  As it says in
> >http://java.sun.com/products/jdk/1.2/docs/guide/rmi/faq.html
> >"it is far too easy to design a class that falls apart under
> >serialization and re-construction."
> 
> Yes, but all the examples mentioned are problems due to
> shifting in time or space, i.e. reconstructing in a different
> runtime environment. The copy we are discussing is assumed to
> happen inside the same (Common Lisp) runtime.


One of the examples is "open file handle".  If I deep-copy an
object that contains a writable file handle, how much of its state
should be shared beteeen the original and the clone?  Obvious
answers:

(a) All of it: obviously both objects need to talk 
to the same stderr.

(b) None of it: obviously the two objects need different
log files.

(I once had this discussion with someone who wanted me to implement
a generic deep-copy.  He finally backed off when I got to "and the
chair he's sitting in, in case he's written the i-node number
on a PostIt stuck to the back?")

imw
From: Tim Bradshaw
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <ey3vgk8dpce.fsf@cley.com>
* Bernhard Pfahringer wrote:

> I beg to differ: there is a *useful* notion of deep copy!
> But probably it should be called a "full copy".
> It is a complete copy of all objects involved with proper
> conservation of all sharing, i.e. each object is copied exactly
> once. E.g. this is what serialization does in Java (*).

Unfortunately this has all sorts of problems.  Although it's useful
for things like GCs it's actually pretty special-purpose.  For
instance what should it do if it is asked to copy a stream object that
refers to an open file?  In general anything that involves references
to real-world objects is fairly painful.  Note that for GC purposes
you don't need to care about this, which is why it is useful there.


>  - full/deep copy (= serialization)
>  - shallow copy/cloning: the minimal reasonable amout of copying

Well, `the minimum reasonable amount of copying' is quite subtle.  For
instance for a queue it involves some copying of the contents of the
queue.  It's not just a straight-forward shallow copy:

    (defmethod copy-queue ((old queue))
      (let ((new (make-instance (class-of queue))))
        (setf (slot-value new 'queue) (slot-value old 'queue)
              (slot-value new 'queue-tail) (slot-value old 'queue-tail))
        new))

Is an *incorrect* copy.

> These two are at either end of a spectrum of "different-depth"
> copiers. But mostly you'll only need those two.
> Therefore it is reasonable for a language to support these
> explicitly.

No, I think that in a almost all cases you need special class or
domain-specific copiers.  That's what I'm trying to say.  In
particular note the domain-specific term: the copier may not only
depend on the class it may also depend on what you are copying it
*for*.

--tim
From: Bernhard Pfahringer
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <9ka6j8$bj$1@hummel.cs.waikato.ac.nz>
In article <···············@cley.com>, Tim Bradshaw  <···@cley.com> wrote:
>* Bernhard Pfahringer wrote:
>
>Is an *incorrect* copy.

Absolutely, so you'd have to implement the correct copier yourself
(override "clone" for queue).

>
>> These two are at either end of a spectrum of "different-depth"
>> copiers. But mostly you'll only need those two.
>> Therefore it is reasonable for a language to support these
>> explicitly.
>
>No, I think that in a almost all cases you need special class or
>domain-specific copiers.  That's what I'm trying to say.  In
>particular note the domain-specific term: the copier may not only
>depend on the class it may also depend on what you are copying it
>*for*.
>

Well, I assume that the class-specific case is much more common
than the domain-specific one. I find it interesting to look at
the Java approach: 
 
 shallow: "clone", a default is provided, but you can roll your
   own, if necessary (class-specific cases, as queue above).

 deep: "serializable", you just indicate you want it, you CANNOT
   change the implementation, only influence the behavior by
   declaring instance vars as "transient" (in which case they are 
   NOT copied).

These two protocols seem to cover a lot of cases. And you can
always implement more special-purpose copiers, should need be.

Can anyone explain how Smalltalk addresses this problem?
What about Dylan? Doesn't Dylan have a generic function
"shallow-copy" that you can add methods to?

cheers, Bernhard
-- 
---------------------------------------------------------------------
Bernhard Pfahringer, Dept. of Computer Science, University of Waikato
http://www.cs.waikato.ac.nz/~bernhard                  +64 7 838 4041
---------------------------------------------------------------------
From: Tim Olson
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <04lzvud73001-0208010855380001@jump-x2-1065.jumpnet.com>
In article <···········@hummel.cs.waikato.ac.nz>,
········@hummel.cs.waikato.ac.nz (Bernhard Pfahringer) wrote:

| Can anyone explain how Smalltalk addresses this problem?

I can't speak for all Smalltalk implementations, but here's how Squeak
handles this:

The Object class provides a number of default copy operations:

clone
   make a copy of the object which shares instance variables (shallow)

shallowCopy
   "public interface" to clone, used to override for things like singletons

copy
   defaults to shallowCopy, general copying method overriden by subclasses
   as required

copyTwoLevel
   copy of object with shallow copy of instance variables

deepCopy
   (recursive) copy of object with deepCopy of all instance variables

veryDeepCopy
   (probably should really be named "structureCopy" or something)
   copies the object, using a dictionary to keep track of the mapping from
   old objects to new objects, so that various identities are preserved


It is up to the various subclasses to override any of these as required,
or implement a new copying interface

-- 

     -- Tim Olson
From: Hannah Schroeter
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <9k66mr$lo2$1@c3po.schlund.de>
Hello!

In article <··············@frown.here>,
Friedrich Dominicus  <·····@q-software-solutions.com> wrote:
>[...]

>Why? You as a programmer have to assure that constraints are
>obeyed. If you mess it up an Exception is raised. The constraint you
>were mentoning can be handeled that way and it's specified and it's
>computer provable. So I can't see where the problem is whith
>specifying such things if you know them.

So you have to write your own implementation of deep_copy for
your QUEUE[T].

Then just don't complain about lisp, and write a

(defgeneric deep-copy (object))
(defmethod deep-copy ((object queue))
  ...)

etc.

Kind regards,

Hannah.
From: ········@hex.net
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <x2z97.36706$uH4.1914386@news20.bellglobal.com>
······@schlund.de (Hannah Schroeter) writes:
> Hello!
> 
> In article <··············@frown.here>,
> Friedrich Dominicus  <·····@q-software-solutions.com> wrote:
> >[...]
> 
> >Why? You as a programmer have to assure that constraints are
> >obeyed. If you mess it up an Exception is raised. The constraint you
> >were mentoning can be handeled that way and it's specified and it's
> >computer provable. So I can't see where the problem is whith
> >specifying such things if you know them.
> 
> So you have to write your own implementation of deep_copy for
> your QUEUE[T].
> 
> Then just don't complain about lisp, and write a
> 
> (defgeneric deep-copy (object))
> (defmethod deep-copy ((object queue))
>   ...)

I expect that everyone could be made happier if this were named a
little more precisely...
 
 (defgeneric deep-*enough*-copy (object))
 (defmethod deep-*enough*-copy ((object queue))
   ...)

:-)
-- 
(concatenate 'string "cbbrowne" ·@acm.org")
http://www.ntlug.org/~cbbrowne/languages.html
"Windows 98  Roast Specialty Blend  coffee beans - just  like ordinary
gourmet coffee except that processing is rushed to leave in the insect
larvae.  Also sold under the ``Chock Full o' Bugs'' brand name..."
From: Kent M Pitman
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <sfw7kwpcfy1.fsf@world.std.com>
······@schlund.de (Hannah Schroeter) writes:

> In article <··············@frown.here>,
> Friedrich Dominicus  <·····@q-software-solutions.com> wrote:
> >[...]
> 
> >Why? You as a programmer have to assure that constraints are
> >obeyed. If you mess it up an Exception is raised. The constraint you
> >were mentoning can be handeled that way and it's specified and it's
> >computer provable. So I can't see where the problem is whith
> >specifying such things if you know them.
> 
> So you have to write your own implementation of deep_copy for
> your QUEUE[T].
> 
> Then just don't complain about lisp, and write a
> 
> (defgeneric deep-copy (object))
> (defmethod deep-copy ((object queue))
>   ...)

This was my reading of this, too.

If the only claim is that the constraints continue to be usable to
detect errors in a new function, that would seem trivially true since
the constraints are about the type, not about the operation.  That
doesn't save me time writing, really (though maybe it saves time
debugging--that would depend on how often the problem happens and how
much time is cost vs how often the constraint is written for nothing).
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <87itg99kjk.fsf@frown.here>
Kent M Pitman <······@world.std.com> writes:

> 
> This was my reading of this, too.
> 
> If the only claim is that the constraints continue to be usable to
> detect errors in a new function, that would seem trivially true since
> the constraints are about the type, not about the operation.  That
> doesn't save me time writing, really (though maybe it saves time
> debugging--that would depend on how often the problem happens and how
> much time is cost vs how often the constraint is written for
> nothing).

Again I suggest to read a bit comp.lang.eiffel and/or
comp.lang.sather. You'll see that this writing of contracts is one of
the pieces in Eiffel, where probably all Eiffel programmers say, that
is one of the greatest features. It expresses what you expect and
guarantee to deliver. It is extracted by the different tools and I do
think it's valuable help in programming. It is a bit of a bridge to
Design.

I do think Common Lisp could gain from that too.

Regards
Friedrich
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <87n15l9kr7.fsf@frown.here>
······@schlund.de (Hannah Schroeter) writes:

> Hello!
> 
> In article <··············@frown.here>,
> Friedrich Dominicus  <·····@q-software-solutions.com> wrote:
> >[...]
> 
> >Why? You as a programmer have to assure that constraints are
> >obeyed. If you mess it up an Exception is raised. The constraint you
> >were mentoning can be handeled that way and it's specified and it's
> >computer provable. So I can't see where the problem is whith
> >specifying such things if you know them.
> 
> So you have to write your own implementation of deep_copy for
> your QUEUE[T].
> 
> Then just don't complain about lisp, and write a
Where in all this mails did I complain about Lisp. It was said that
ther is not language with a deep_copy. I pointed out Eiffel and was
told that is can not work. S please read the thread.

Regards
Friedrich
From: Marco Antoniotti
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <y6cae1myzvf.fsf@octagon.mrl.nyu.edu>
Friedrich Dominicus <·····@q-software-solutions.com> writes:

> Tim Bradshaw <···@cley.com> writes:
> 
> > * Friedrich Dominicus wrote:
> > > Fernando <···@wanadoo.es> writes:
> > 
> > >> Not really, there's no automagic way of making deep copies of
> > objects (in CLOS
> > >> or any other OOP).
> > > Is it really? Now in Eiffel I wrote deep_copy and got it. So probably
> > > I'm missing something.
> > 
> > Would your automatic deep copier deal correctly with this class:
> > 
> > (defclass fifo ()
> >   ((queue :initform '())
> >    (queue-tail :initform nil)))
> > 
> > (hint: in order to work, the copier has to ensure that if the QUEUE
> > slot is non-NIL then QUEUE-TAIL must be the last cons in QUEUE).
> hint. in Eiffel one specfied the characteristics either by Pre or
> Postconditions or invariants. You class would probably look like this
> in Eiffel
> 
> class FIFO[G]
> 
> creation
>    make ..
> 
> feature
>    queue : LIST [G];
>    tail : G
> 
> 
> invariant
> tail_constraint: tail = queue.item(count);
> 
> or the like
> 
> If I do a deep-clone all assertions have to be fullfilled for the
> constraints too.
> 
> So If I have a
> a : FIFO[FOO];
> b : FIFO[FOO];
> 
> I got a full copy with
> b := a.deep_clone;
> 
> So I can be sure that the constraint tail = queue.item(count) will
> hold.
> 
> BTW I do think that one of the next addings to Common Lisp should be
> features for Design by Contract. I know that there is a package for
> it, anyway that should be standardized. Tools should be used to extrac
> a) the documentation (as it is done nicely in Common Lisp)
> b) the contracts (which are lacking in Common Lisp)

This is all nice and good.  However, you are just guaranteed that the
invariant holds (or not).  It does not ease your job to actually write
a "deep_copy" function that applies to the Queue (AFAIU).

As an alternative, you can say (and maybe that is the case in Eiffel)
that le language (or language library) gives you the "deep_copy"
operation and that its use on the Queue above will raise an error
somewhere (either at compile time or at run time: I just do not know).

The bottom line does not change.  Deep Copy is too tricky to be
defined correctly in a completely general term.

Cheers


-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
                    "Hello New York! We'll do what we can!"
                           Bill Murray in `Ghostbusters'.
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <87wv4p32uu.fsf@frown.here>
Marco Antoniotti <·······@cs.nyu.edu> writes:

> 
> As an alternative, you can say (and maybe that is the case in Eiffel)
> that le language (or language library) gives you the "deep_copy"
> operation and that its use on the Queue above will raise an error
> somewhere (either at compile time or at run time: I just do not
know).

deep_copy is defined in Eiffel and it will not raise an error, because
all constraints must hold for a copy too.
> 
> The bottom line does not change.  Deep Copy is too tricky to be
> defined correctly in a completely general term.
it is defined in Eiffel and I posted an example. I do not care if it's
tricky to implement. I use it.

Regards
Friedrich
From: Marco Antoniotti
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <y6cvgk9xfsj.fsf@octagon.mrl.nyu.edu>
Friedrich Dominicus <·····@q-software-solutions.com> writes:

> Marco Antoniotti <·······@cs.nyu.edu> writes:
> 
> > 
> > As an alternative, you can say (and maybe that is the case in Eiffel)
> > that le language (or language library) gives you the "deep_copy"
> > operation and that its use on the Queue above will raise an error
> > somewhere (either at compile time or at run time: I just do not
> know).
> 
> deep_copy is defined in Eiffel and it will not raise an error, because
> all constraints must hold for a copy too.
> > 
> > The bottom line does not change.  Deep Copy is too tricky to be
> > defined correctly in a completely general term.
> it is defined in Eiffel and I posted an example. I do not care if it's
> tricky to implement. I use it.

So, you are saying that the Eiffel compiler is capable of compiling a
'deep_clone' operation (or a java.lang.Clonable interface) for a user
defined class no matter how intricate and "untree-like" its contents
are.  I am not debating this.  I am impressed by how complex an Eiffel
compiler must be.  Yet, not knowing the details, I have the right to
remain dubious about the overall results.

Cheers

-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
                    "Hello New York! We'll do what we can!"
                           Bill Murray in `Ghostbusters'.
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <87hevs46mj.fsf@frown.here>
Marco Antoniotti <·······@cs.nyu.edu> writes:

> 
> So, you are saying that the Eiffel compiler is capable of compiling a
> 'deep_clone' operation (or a java.lang.Clonable interface) for a user
> defined class no matter how intricate and "untree-like" its contents
> are.  I am not debating this.  I am impressed by how complex an Eiffel
> compiler must be.
Eiffel compiler need to know all about their system. But that's not
too bad because you can not add things during run-time. E.g if you
have an object it can not change it's class and such things. Ken
posted an example where deep_copy does probably fail. If unique things
come into play I now stand corrected that deep_copy does not the
"right" thing always and under all circumstances. But till now I did
not have found any case in which deep_clone failed to yield
field-by-field identical copy of the original object. 

As pointed out in another message, the usage of deep_copy is probably
limited. Sometimes you really need it, sometimes you can work around,
and most of the time you better reorganize your code.

Regards
Friedrich
From: Kent M Pitman
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <sfw8zh5cg5i.fsf@world.std.com>
Friedrich Dominicus <·····@q-software-solutions.com> writes:

> Marco Antoniotti <·······@cs.nyu.edu> writes:
> 
> > As an alternative, you can say (and maybe that is the case in Eiffel)
> > that le language (or language library) gives you the "deep_copy"
> > operation and that its use on the Queue above will raise an error
> > somewhere (either at compile time or at run time: I just do not
> > know).

> deep_copy is defined in Eiffel and it will not raise an error, because
> all constraints must hold for a copy too.

> > The bottom line does not change.  Deep Copy is too tricky to be
> > defined correctly in a completely general term.
>
> it is defined in Eiffel and I posted an example.

We saw the example and many of us didn't find it compelling, especially
absent an explanation.  We aren't seeking proof that it's present in the
language, we are seeking proof that it's something we could use--that is,
that we are even on the same wavelength about what the meaning is and
whether it's appropriate to have in an application.

Common Lisp has gentemp, for example, but that turns out not to be a proof
that it's ever really possible to use for anything safe.

> I do not care if it's tricky to implement. I use it.

Perhaps you can offer some examples of how it handles copying of structures
with slots like the following.  It's not just that I wonder if it can be
done (though I do) but also I'm curious of how much textual work it is to
do (so I can compare with the textual work of just writing an appropriate
copy).  Does it also write deep_equal for you?

 unique-id
 unique-id-as-french-text
 first-created-timestamp
 last-touched
 age
 wife
 grandmothers-nickname-for-me
 pgp-private-key
 next-prime-after-unique-id
 lists-i-am-a-member-of
 lists-i-am-not-a-member-of
 number-of-clones-of-me
 slanders-against-my-identity
 bank-account-number
 personal-wealth
 good-hash-key
From: Lieven Marchand
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <m3snfe496r.fsf@localhost.localdomain>
Friedrich Dominicus <·····@q-software-solutions.com> writes:

> Tim Bradshaw <···@cley.com> writes:
> 
> > * Friedrich Dominicus wrote:
> > > Fernando <···@wanadoo.es> writes:
> > 
> > >> Not really, there's no automagic way of making deep copies of
> > objects (in CLOS
> > >> or any other OOP).
> > > Is it really? Now in Eiffel I wrote deep_copy and got it. So probably
> > > I'm missing something.
> > 
> > Would your automatic deep copier deal correctly with this class:
> > 
> > (defclass fifo ()
> >   ((queue :initform '())
> >    (queue-tail :initform nil)))
> > 
> > (hint: in order to work, the copier has to ensure that if the QUEUE
> > slot is non-NIL then QUEUE-TAIL must be the last cons in QUEUE).
> hint. in Eiffel one specfied the characteristics either by Pre or
> Postconditions or invariants. You class would probably look like this
> in Eiffel
> 
> class FIFO[G]
> 
> creation
>    make ..
> 
> feature
>    queue : LIST [G];
>    tail : G
> 
> 
> invariant
> tail_constraint: tail = queue.item(count);
> 
> or the like
> 

Your example is not equivalent to Tims. In his class there could be a
feature

(defmethod append ((q fifo) element)
  (setf (cdr (queue-tail q)) (cons element nil))
  (setf (queue-tail q) (cdr queue-tail q)))

You just cache the last item.

PS: for the record, I have read OOSC 2nd. Edition and I do not
consider it the towering master piece you seem to make of it. It's a
useful debating trick though. "Go read this 1000+ page book and then
we'll talk further"

-- 
Lieven Marchand <···@wyrd.be>
You can drag any rat out of the sewer and teach it to get some work done in
Perl, but you cannot teach it serious programming.              Erik Naggum
From: Tim Bradshaw
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <ey3elqyulsw.fsf@cley.com>
* Lieven Marchand wrote:

> (defmethod append ((q fifo) element)
>   (setf (cdr (queue-tail q)) (cons element nil))
>   (setf (queue-tail q) (cdr queue-tail q)))

Oh, yes, that was the intention.  The full implementation would be
something like this:

    (defgeneric enqueue (object queue)
      ;; return OBJECT
      )
    (defgeneric dequeue (queue)
      ;; return ob and t or nil and nil
      )
    (defgeneric queue-empty-p (queue)
      ;; t/nil
      )

    (defclass queue ()
      ((queue :initform '())
       (queue-tail :initform '())))

    (defmethod enqueue (object (queue queue))
      (with-slots (queue queue-tail) queue
        (if (null queue)
            (setf queue (list object)
                  queue-tail queue)
          (setf (cdr queue-tail) (list object)
                queue-tail (cdr queue-tail))))
      object)

    (defmethod dequeue ((queue queue))
      (with-slots (queue queue-tail) queue
        (if (null queue)
            (values nil nil)
          (values
           (prog1 (car queue)
             (setf queue (cdr queue))
             ;; not stricly needed
             (when (null queue)
               (setf queue-tail '())))
           t))))

    (defmethod queue-empty-p ((queue queue))
      (null (slot-value queue 'queue)))

It would be interesting to see an automatically generated `deep-copy'
for this.  My code to copy queues would be this:

    (defgeneric copy-queue (queue))

    (defmethod copy-queue ((queue queue))
      (let ((new (make-instance (class-of queue))))
        (setf (slot-value new 'queue)
              (copy-list (slot-value queue 'queue))
              (slot-value new 'queue-tail)
              (last (slot-value new 'queue)))
        new))

Note that the underlying list is only shallowly copied: one could
argue that this is not therefore a deep copy: so be it, but it's the
copy you *want* in almost all cases.

--tim
From: Tim Bradshaw
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <ey3u1zttqjs.fsf@cley.com>
* I wrote:

> Note that the underlying list is only shallowly copied: one could
> argue that this is not therefore a deep copy: so be it, but it's the
> copy you *want* in almost all cases.

I thought about this last night, and I'd kind of like to set it as a
challenge to anyone who wants to defend automatically-generated copy
methods.

If I have some object which represents a queue of other objects, then
a useful (I get to define useful here) copy of this object should be a
queue of the same, identical objects, *not* a queue of copies of those
objects.  Given the implementation of a queue I gave this requires an
interesting combination of copy-preserving-sharing (for the underlying
list of items and the tail pointer) with no copy of the members of the
list.

I would like to see a system that can express - in some declarative
way such as a constraint language - this notion of copying a queue.

--tim
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <871ymx4hjm.fsf@frown.here>
Tim Bradshaw <···@cley.com> writes:

> * Lieven Marchand wrote:
> 
> > (defmethod append ((q fifo) element)
> >   (setf (cdr (queue-tail q)) (cons element nil))
> >   (setf (queue-tail q) (cdr queue-tail q)))
> 
> Oh, yes, that was the intention.  The full implementation would be
> something like this:
> 
>     (defgeneric enqueue (object queue)
>       ;; return OBJECT
>       )
>     (defgeneric dequeue (queue)
>       ;; return ob and t or nil and nil
>       )
>     (defgeneric queue-empty-p (queue)
>       ;; t/nil
>       )
> 
>     (defclass queue ()
>       ((queue :initform '())
>        (queue-tail :initform '())))
> 
>     (defmethod enqueue (object (queue queue))
>       (with-slots (queue queue-tail) queue
>         (if (null queue)
>             (setf queue (list object)
>                   queue-tail queue)
>           (setf (cdr queue-tail) (list object)
>                 queue-tail (cdr queue-tail))))
>       object)
> 
>     (defmethod dequeue ((queue queue))
>       (with-slots (queue queue-tail) queue
>         (if (null queue)
>             (values nil nil)
>           (values
>            (prog1 (car queue)
>              (setf queue (cdr queue))
>              ;; not stricly needed
>              (when (null queue)
>                (setf queue-tail '())))
>            t))))
> 
>     (defmethod queue-empty-p ((queue queue))
>       (null (slot-value queue 'queue)))
> 
> It would be interesting to see an automatically generated `deep-copy'
> for this.  My code to copy queues would be this:
Now you copy is a Lisp solution and uses the facilities from Common
Lisp which is ok. I've used the Eiffel facilities in Eiffel and will
not "re-write" Lisp in Eiffel. If the behavior of my program is queueish
it's done for me. Because we are discussing Common Lisp here I better
do not post a Eiffel-ish solution here. Just in Eiffel it is guranteed
that using deep_copy yield an independent object and it is not a
shallow copy. If you want to see a Eiffel solution you can check out
the existing Eiffel libraries or if you want we can talk about it in
comp.lang.misc.


> 
>     (defgeneric copy-queue (queue))
> 
>     (defmethod copy-queue ((queue queue))
>       (let ((new (make-instance (class-of queue))))
>         (setf (slot-value new 'queue)
>               (copy-list (slot-value queue 'queue))
>               (slot-value new 'queue-tail)
>               (last (slot-value new 'queue)))
>         new))
> 
> Note that the underlying list is only shallowly copied: one could
> argue that this is not therefore a deep copy: so be it, but it's the
> copy you *want* in almost all cases.
Now that does disturb me a bit, just that you want it usually does not
mean you want it always to be it that way. Here is an Eiffel Queue and
a class in which you can see that:

indexing
	description: "Objects that ..."
	author: ""
	date: "$Date: 1999/01/12 01:57:05 $"
	revision: "$Revision: 1.3 $"

class
	MY_QUEUE [G]

creation
	make

feature -- Initialization

	make is
			-- Initialize
		do
			!!store.make
            
		ensure
			store_valid : store /= Void;
		end

feature -- Access
    queue (new_item : G) is
            -- put item at front
        do
            store.put_front (new_item);
        ensure
            item_put_at_front: store.first = new_item;
        end;

    item : G is
        require
            not_empty: not empty;
        do
            Result := store.last;
        ensure
            Result = store.last;
        end;
    
    remove is
            -- remove the last element
        require
            not_empty : not empty;
        do
            store.finish;
            store.remove;
        ensure
            removed: store.count = old store.count -1;
        end;
            
    

    empty : BOOLEAN is
        do
            Result := store.empty;
        end;
        

feature {NONE} -- Implementation
    store : TWO_WAY_LIST [G]

invariant
	item_constraint: not empty implies item.is_equal(store.last);

end -- class MY_QUEUE


class QUEUE_TEST


creation
    make


feature
    a : MY_QUEUE[ARRAY[INTEGER]];
    b : MY_QUEUE[ARRAY[INTEGER]];
    c : like a;

    make is
        do
            !!a.make;
            a.queue(<<1,2>>);
            print_item (a.item);
            a.queue(<<3,4>>);
            print_item(a.item);
            
            b := a.clone(a);
            print_queue (b, "-------------------%Nb= ");
            make_a;
            b := a.clone(a);
            a.remove;
            print_queue(a, "a= ");
            make_a;
            b := a.clone(a);
            a.remove;
            print_queue(b, "b= ");
            make_a;
            b := a.deep_clone(a);
            a.remove;
            print_queue(b, "b=");
        end;


    make_a is
        do
            !!a.make;
            a.queue(<<1, 2>>);
            a.queue(<<3,4>>);
        end;


    print_queue (queue : like a; msg: STRING) is
        do
            io.put_string(msg);
            io.new_line;
            from
            until queue.empty
            loop
                print_item(queue.item);
                queue.remove;
            end
         end;


    print_item (arr_i: ARRAY[INTEGER]) is
        local
            i : INTEGER;
        do
            from i := arr_i.lower;
            until i > arr_i.upper
            loop
                io.put_string("arr(");
                io.put_integer(i);
                io.put_string(") = ");
                io.put_integer(arr_i.item(i));
                if i < arr_i.upper then
                    io.put_string(",");
                end;
                i := i + 1;
            end;
            io.new_line;
        end;
end -- class QUEUE_TEST

output is:
-------------------
b= 
arr(1) = 1,arr(2) = 2
arr(1) = 3,arr(2) = 4
a= 
arr(1) = 3,arr(2) = 4
b= 
arr(1) = 3,arr(2) = 4
b=
arr(1) = 1,arr(2) = 2
arr(1) = 3,arr(2) = 4

you see that shallow copy simply does not work here, but a deep
copy.


Regards
Friedrich
From: Tim Bradshaw
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <ey3ofq1to85.fsf@cley.com>
* Friedrich Dominicus wrote:

> If you want to see a Eiffel solution you can check out
> the existing Eiffel libraries or if you want we can talk about it in
> comp.lang.misc.
> [...]

> indexing
> 	description: "Objects that ..."
> 	author: ""
> 	date: "$Date: 1999/01/12 01:57:05 $"
> 	revision: "$Revision: 1.3 $"

> [...]

I'm afraid I find this trick of failing to answer any specific
problems raised, suggesting the question should be discussed in a
different newsgroup and quoting extended examples in a formalism that
it's unreasonable to expect people here to understand pretty
irritating.  If you want to discuss deep copying do it in Lisp or
English, and try and actually answer the questions you are asked
rather than evading them.

I don't have any more time to deal with this kind of thing.

--tim
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <87wv4p9u5s.fsf@frown.here>
Tim Bradshaw <···@cley.com> writes:

> * Friedrich Dominicus wrote:
> 
> > If you want to see a Eiffel solution you can check out
> > the existing Eiffel libraries or if you want we can talk about it in
> > comp.lang.misc.
> > [...]
> 
> > indexing
> > 	description: "Objects that ..."
> > 	author: ""
> > 	date: "$Date: 1999/01/12 01:57:05 $"
> > 	revision: "$Revision: 1.3 $"
> 
> > [...]
> 
> I'm afraid I find this trick of failing to answer any specific
> problems raised, suggesting the question should be discussed in a
> different newsgroup and quoting extended examples in a formalism that
> it's unreasonable to expect people here to understand pretty
> irritating.

Now and I find it irritating to just state a deep_copy can't work. As
I pointed out I will discuss that in another group. But it was you and
other which just said a deep_copy does not make sense. Now as I
pointed out it's defined and it has worked in Eiffel of years
now. Anyway I will shut up on this because it's obvious that not it's
the wront group and the wrong discussion partner obviously.
> 
> I don't have any more time to deal with this kind of thing.
Great then do not state such things as "it can't give a deep_copy"

Friedrich
From: Fred Gilham
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <u7g0bdjid6.fsf@snapdragon.csl.sri.com>
Friedrich Dominicus <·····@q-software-solutions.com> writes:

> Tim Bradshaw <···@cley.com> writes:
> 
> > * Friedrich Dominicus wrote:
> > 
> > > If you want to see a Eiffel solution you can check out
> > > the existing Eiffel libraries or if you want we can talk about it in
> > > comp.lang.misc.
> > > [...]
> > 
> > > indexing
> > > 	description: "Objects that ..."
> > > 	author: ""
> > > 	date: "$Date: 1999/01/12 01:57:05 $"
> > > 	revision: "$Revision: 1.3 $"
> > 
> > > [...]
> > 
> > I'm afraid I find this trick of failing to answer any specific
> > problems raised, suggesting the question should be discussed in a
> > different newsgroup and quoting extended examples in a formalism that
> > it's unreasonable to expect people here to understand pretty
> > irritating.
> 
> Now and I find it irritating to just state a deep_copy can't work. As
> I pointed out I will discuss that in another group. But it was you and
> other which just said a deep_copy does not make sense. Now as I
> pointed out it's defined and it has worked in Eiffel of years
> now. Anyway I will shut up on this because it's obvious that not it's
> the wront group and the wrong discussion partner obviously.
> > 
> > I don't have any more time to deal with this kind of thing.
> Great then do not state such things as "it can't give a deep_copy"
> 

This seems to me to be a standard `worse is better' kind of
discussion.  On the one hand, Friedrich Dominicus says that Eiffel
provides a perfectly usable deep copy that does what it purports to
do, and he will happily use it, thank you.

On the other hand, Tim (and other lispers) argue that a deep copy,
even one that does what it claims to do, will do the wrong thing in
some real-world instances, and therefore the language should not
provide such a feature.  Instead, programmers must retain the
responsibility of deciding what they intend when they copy an object,
and implement that intent themselves.

I'm not saying that there's no point in arguing about the issue.  Such
arguments clarify the technical issues and are necessary to make a
determination on merits possible.

I think one can conclude that if lisp were to adopt a deep copy it
would go against the underlying philosophy that has guided its
development and thus tend to make the language incoherent.  A language
user develops expectations about the way the constructs in a language
will behave, and if some of them don't behave that way, the user will
be unpleasantly surprised.

-- 
Fred Gilham                                    ······@csl.sri.com
Do remember you're there to fuddle him.  From the way some of you
young fiends talk, anyone would suppose it was our job to teach!
                          -- The Screwtape Letters, C. S. Lewis
From: Kent M Pitman
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <sfwitg7n6fd.fsf@world.std.com>
Fred Gilham <······@snapdragon.csl.sri.com> writes:

> This seems to me to be a standard `worse is better' kind of
> discussion.  On the one hand, Friedrich Dominicus says that Eiffel
> provides a perfectly usable deep copy that does what it purports to
> do, and he will happily use it, thank you.
> 
> On the other hand, Tim (and other lispers) argue that a deep copy,
> even one that does what it claims to do, will do the wrong thing in
> some real-world instances, and therefore the language should not
> provide such a feature.  Instead, programmers must retain the
> responsibility of deciding what they intend when they copy an object,
> and implement that intent themselves.
> 
> I'm not saying that there's no point in arguing about the issue.  Such
> arguments clarify the technical issues and are necessary to make a
> determination on merits possible.

I agree up to here.
 
> I think one can conclude that if lisp were to adopt a deep copy it
> would go against the underlying philosophy that has guided its
> development and thus tend to make the language incoherent.  A language
> user develops expectations about the way the constructs in a language
> will behave, and if some of them don't behave that way, the user will
> be unpleasantly surprised.

The weird thing is that I find the same set of issues as for copy to
be active for EQUAL.  It's quite eerie to me how many people use EQUAL
in the face of it's really unsemantic and clumsy nature.  I think in
general they run a small proof engine over the set of types they will
use and try to conclude that it will be satisfactory for the purpose.
At least it doesn't have the "copying an open file" problem someone
cited; but it still has some very analogous problems, like detecting
whether (make-broadcast-stream file) and file are the same file;
whether they are or are not is probably application-specific.  But
most programmers in Lisp would rather bumble through with EQUAL than
write their own EQUAL because the latter is too much work to do over
just to change one fringe case.  (I think this reveals something deep
about the way human beings think about problems, too.)

When we wrote CLTL (the original) and were surveying the various 
dialects of Lisp contributing to the project, it was plain that NONE 
of them agreed on the definitions of SUBST or EQUAL.  I proposed not
including them as a consequence, and letting them be user-defined.
I think others suggested adding EQUALP would "give customers more choice".
More choice of what? I argued--it's as ill-defined (well, that's probably
the wrong word--"arbitrarily defined, and statistically unlikely to be
right for any given purpose" is perhaps better) as EQUAL.  But the 
compelling argument to the design committee of the time, as I recall,
was that "everyone was used to having EQUAL" and "they would be mad
if it wasn't there".  Once again (I told another story like this the
other day), it was the _name_ that people were attached to, as I think
peopke are attached to the name copy.  And I think they secretly understand
that writing this function, though it seems a simple recursive procedure,
is in general very hard to get right.  So I sometimes wonder if it's
just that they'd rather have the plausible deniability of having a
generically named function that "seemed like the right thing" that they
could blame subtle errors on than write that same function themselves
and have to defend as to the actual correctness for purpose of their
application.  Just a thought.  Maybe most programmers don't think that 
hard about it...
From: Kent M Pitman
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <sfwae1lcgus.fsf@world.std.com>
Friedrich Dominicus <·····@q-software-solutions.com> writes:

> Tim Bradshaw <···@cley.com> writes:
> 
> > * Friedrich Dominicus wrote:
> > 
> > > If you want to see a Eiffel solution you can check out
> > > the existing Eiffel libraries or if you want we can talk about it in
> > > comp.lang.misc.
> > > [...]
> > 
> > > indexing
> > > 	description: "Objects that ..."
> > > 	author: ""
> > > 	date: "$Date: 1999/01/12 01:57:05 $"
> > > 	revision: "$Revision: 1.3 $"
> > 
> > > [...]
> > 
> > I'm afraid I find this trick of failing to answer any specific
> > problems raised, suggesting the question should be discussed in a
> > different newsgroup and quoting extended examples in a formalism that
> > it's unreasonable to expect people here to understand pretty
> > irritating.
> 
> Now and I find it irritating to just state a deep_copy can't work.

We didn't just state it.  We pointed to at least my paper on it, which
is a paper written in English and using Lisp code examples.  If you
want, I'll paste it into the newsgroup and it will continue to be on
topic.  It operates as little more than a FAQ on this topic--it's written
to Lisp people and treats this topic directly, not as an incidental matter.
 
If you have some out-of-band information readable by someone
with Lisp experience, please feel free to post it here, but I
think Tim's on target here by saying that it's not the obligation of
people here to go out and learn other languages just to be able to
continue conversation.  It is an opportunity for those with other
language background to contriibute here if they can and want to
translate their concepts for consumption here.  Otherwise, anyone can
trivially trump anyone else by citing an obscure paper written in
Navajo (picked here as an examplee only in honor of Dubya's recent
award to them for their service in using their native tongue as an
encryption mechanism in World War II), and by virtue of not being able
to track down, read, or refute the cite, it does seem you want us to
declare your knowledge superior.  That isn't how legitimate debate
works.

> As I pointed out I will discuss that in another group. But it was
> you and other which just said a deep_copy does not make sense. Now
> as I pointed out it's defined and it has worked in Eiffel of years
> now.

Then your obligation is, as Tim suggests, to explain how that works in
terms meaningful to us here.  It is not our obligation to speculatively
assume that every claim made by every person who visits here from afar
is right, and to enroll in every course they suggest or read every paper
they cite, at peril of being found to be closed-minded.  We are a discussion
group, not a thesis student.

> Anyway I will shut up on this because it's obvious that not it's
> the wront group and the wrong discussion partner obviously.

This is a false conclusion.  The indicated action at this point is not to
shut up but just the reverse--to explain in terms people here can understand
how Eiffel manages.  If it can be done, I think people wnat to understand
it.

> > I don't have any more time to deal with this kind of thing.
>
> Great then do not state such things as "it can't give a deep_copy"

This is not a legitimate conclusion.  Fermat got away with this kind of 
thing (assertion by absent refutation).  But as a rule, the burden is on
the person claiming the amazing thing to show it true, not on the people
who reasonably disbelieve to show it false.

(Then again, I never understood why in the bootstrapping of calculus the
people with the deltas always got the advantage.  I was always rooting for
the epsilons, and felt they should sometimes get to go first.  Of course
one was always bigger than the other if they controlled the order of the
choice. If I'd known they were going to pick THAT epsilon, I could have 
picked a delta smaller.  Oh, never mind me... :-)
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <87elqx9keo.fsf@frown.here>
Kent M Pitman <······@world.std.com> writes:

> 
> Then your obligation is, as Tim suggests, to explain how that works in
> terms meaningful to us here.  It is not our obligation to speculatively
> assume that every claim made by every person who visits here from afar
> is right, and to enroll in every course they suggest or read every paper
> they cite, at peril of being found to be closed-minded.  We are a discussion
> group, not a thesis student.
Well you are rigth, I will not continue with it. Anyway the first
point that there isnt's a language in which deep_copy is implemented
or whatever and that is simply wrong.

> This is a false conclusion.  The indicated action at this point is not to
> shut up but just the reverse--to explain in terms people here can understand
> how Eiffel manages.  If it can be done, I think people wnat to understand
> it.
I can not discuss in Eiffel terms here. And so I can not "disucss it
further"

Regards
Friedrich
From: Thom Goodsell
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <7v66c9nhls.fsf@shalott.cra.com>
Friedrich Dominicus <·····@q-software-solutions.com> writes:
> Well you are rigth, I will not continue with it. Anyway the first
> point that there isnt's a language in which deep_copy is implemented
> or whatever and that is simply wrong.

I think you've missed the point that people here have been trying to
make.  No one doubts that a function called deep_copy (or some
variant) exists in Eiffel, but we doubt that it does the "right thing"
in all cases because a correct deep copy requires knowledge that is
usually not present in the data structure.

IIUC you claim that in Eiffel this knowledge can be encoded in the
constraints and that the compiler can then generate a semantically
correct deep_copy function. While many of us our doubtful that this
always does the right thing, I for one wouldn't mind being proven
wrong. At the very least, I would like to know what Eiffel is doing,
to learn from it.

So, please explain what Eiffel is doing. What is the default behavior
of deep_copy, absent any constraints? How does adding constraints
change the behavior of deep_copy? Can you give us a pseudo-code or
"Lispy Eiffel" example of a simple case? 

> I can not discuss in Eiffel terms here. And so I can not "disucss it
> further"

The problem isn't that we don't like Eiffel terms; it's that we don't
understand them. If I wrote this whole post in Portguese, I'd get much
the same response: "That's nice, but can you explain it in English?"
There are undoubtedly others in the newsgroup who understand
Portuguese, but the vast majority do not.

The Eiffel terms are undoubtedly useful, but many of us don't know the
language. Please, explain the concepts in either Lisp terms, English
explanations, or some combination of the two.

Thom

-- 
Thom Goodsell                           ···@cra.com
Scientist                       (617) 491-3474 x574
Charles River Analytics         http://www.cra.com/
From: Barry Margolin
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <92E97.23$TO3.123@burlma1-snr2>
In article <··············@shalott.cra.com>,
Thom Goodsell  <···@cra.com> wrote:
>So, please explain what Eiffel is doing. What is the default behavior
>of deep_copy, absent any constraints? How does adding constraints
>change the behavior of deep_copy? Can you give us a pseudo-code or
>"Lispy Eiffel" example of a simple case? 

I haven't studied Eiffel, but the impression I got from his example is
*not* that the constraints cause deep_copy to do the "right thing" for this
object type.  Instead, the constraint mechanism can be used to catch cases
where you use deep_copy on inappropriate types.  If deep copying results in
an object that doesn't satisfy the constraints, an exception will be raised
instead of the object being returned.

Lisp certainly could have a generic DEEP-COPY function similar to
Eiffel's.  But without something like Eiffel's constraint mechanism, such a
function is open to too much misuse.  When programmers see a function built
into the language, they seem to have high expectations about it; we didn't
want to suggest that this function is widely applicable.  Others have
mentioned a hypothetical DEEP-ENOUGH-COPY, but knowing when enough is
enough requires semantic information about the application (it's not even a
type-dependent thing -- if you're copying a Lisp cons, you need to know
whether the application considers it to be part of a tree, list, alist,
etc., which is why we have COPY-TREE, COPY-LIST, and COPY-ALIST rather than
just COPY-CONS).

We could also add constraints to the language to perform checks like Eiffel
does, but that only addresses part of the problem.  As pointed out, whether
a particular operation makes sense depends on the context, not just the
type algebra.

-- 
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: Kent M Pitman
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <sfw3d7c6d9p.fsf@world.std.com>
Barry Margolin <······@genuity.net> writes:

> I haven't studied Eiffel, but the impression I got from his example is
> *not* that the constraints cause deep_copy to do the "right thing" for this
> object type.  Instead, the constraint mechanism can be used to catch cases
> where you use deep_copy on inappropriate types.

Except for the fact that I think some constraints are hard to
represent programmatically, I'd think this was ok.  My problem is that
I bet some people don't specify constraints because the language makes
it too hard to put them in.  Then there's a blame game about who erred
by using deep_copy inappropriately.  I think when the language makes
it hard (or unreasonably gives you reason to believe it should be easy
or even possible or assumes that possible implies computationally
tractable) to write certain constraints, the language is at fault, not
the person who couldn't be bothered.
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <87puag473p.fsf@frown.here>
Kent M Pitman <······@world.std.com> writes:

> Barry Margolin <······@genuity.net> writes:
> 
> > I haven't studied Eiffel, but the impression I got from his example is
> > *not* that the constraints cause deep_copy to do the "right thing" for this
> > object type.  Instead, the constraint mechanism can be used to catch cases
> > where you use deep_copy on inappropriate types.
> 
> Except for the fact that I think some constraints are hard to
> represent programmatically, I'd think this was ok.

This is true. And in fact there are weak points in the way Eiffel
handle it. In Eiffel there is a culture of "writing assertions" and
programmers put some other constraints on themselves. E.g the
distinguish between command and queries. The commands are there to
change the state of an object and queures are there to ask an object
about it's state. The first should have side-effects and the latter
must not!

This it obviously totally contraty to the Lisp-way. Just Lisp offers
some pieces which are simply not there in Eiffel. E.g you do not have
"standardized" higher order functions in Eiffel. That is one of the
biggest flaws in Eiffel. In Common Lisp I can express much more
constraints on containers easily than I ever will in Eiffel.


>My problem is that
> I bet some people don't specify constraints because the language makes
> it too hard to put them in.
Now not in Eiffel. All (somewhat good) Eiffel programmers will use
Assertions. You get used to them and they won't let you go again ;-)

Regards
Friedrich
From: ···@itasoftware.com
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <snfbhcwq.fsf@itasoftware.com>
Kent M Pitman <······@world.std.com> writes:

> Barry Margolin <······@genuity.net> writes:
> 
> > I haven't studied Eiffel, but the impression I got from his example is
> > *not* that the constraints cause deep_copy to do the "right thing" for this
> > object type.  Instead, the constraint mechanism can be used to catch cases
> > where you use deep_copy on inappropriate types.
> 
> Except for the fact that I think some constraints are hard to
> represent programmatically, I'd think this was ok.  My problem is that
> I bet some people don't specify constraints because the language makes
> it too hard to put them in.  

Well then, we'll have to make sure the compiler doesn't produce a
single byte of object code unless it can prove that *all* constrants
work, and we'll eliminate any sort of `catch all', `universal', or
`deferred until runtime' constraint.  That'll teach 'em.
From: Kent M Pitman
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <sfwwv4p6oiu.fsf@world.std.com>
Friedrich Dominicus <·····@q-software-solutions.com> writes:

> Kent M Pitman <······@world.std.com> writes:
> 
> > 
> > Then your obligation is, as Tim suggests, to explain how that
> > works in terms meaningful to us here.  It is not our obligation to
> > speculatively assume that every claim made by every person who
> > visits here from afar is right, and to enroll in every course they
> > suggest or read every paper they cite, at peril of being found to
> > be closed-minded.  We are a discussion group, not a thesis
> > student.
>
> Well you are rigth, I will not continue with it.

That's your choice.  Don't feel like we asked for that outcome.
I've only heard people say they want you to speak, not that they
want you not to... They just want you to explain what you're saying.

> Anyway the first point that there isnt's a language in which
> deep_copy is implemented or whatever and that is simply wrong.

No one is disputing that there is such a function.  They are disputing
that it would be useful to us.  To understand that, they need to understand
what it does or does not do.

As cbbrowne pointed out in another thread, the issue is not deep but
deep-enough (not too shallow, not too deep, etc.)
 
> > This is a false conclusion.  The indicated action at this point is
> > not to shut up but just the reverse--to explain in terms people
> > here can understand how Eiffel manages.  If it can be done, I
> > think people wnat to understand it.
>
> I can not discuss in Eiffel terms here. And so I can not "disucss it
> further"

Certainly you can discuss Eiffel terms here.  You just have to explain 
them.  It can't be the responsibility of everyone who wants to learn
what you have to say to go look up the terms you are using.  That is bad
modularity.
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <87u1zs47fn.fsf@frown.here>
Kent M Pitman <······@world.std.com> writes:

> 
> That's your choice.  Don't feel like we asked for that outcome.
> I've only heard people say they want you to speak, not that they
> want you not to... They just want you to explain what you're saying.

Ok, I try to state it hopefully correctly but will not be sure to
always use the "correct" Lisp terminology.

Someone else in this thread pointed out what "a meaningful definition
of deep_xxx could be.

In Eiffel it's a recursive one-to-one copy from all the objects which
can be reached by the top-instance, which should be copied.


So in you unique-id case you won't have a unique-id any longer. Now
that would prove that there is not a general way of deep_copying
objects. In Eiffel deep_copy is defined in terms of deep_equal. That
means you would have to "roll your own" copy routine which would
assign e.g a really unique_id, and deep_equal routine. In that case I
stand corrected. There is no unique way of copying objects.

I did not have encountered a case as you pointed out before in all my
Programs and in fact I was and am probably  too much into Eiffel that
I could not break out. The defined behavior of deep_copy is
nevertheless very useful I showed a case in which you can not get
along with just a "shallow copy"

Regards
Friedrich
From: Coby Beck
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <OsB97.56606$Gh1.8649172@typhoon.tampabay.rr.com>
"Friedrich Dominicus" <·····@q-software-solutions.com> wrote in message >
Well you are rigth, I will not continue with it. Anyway the first
> point that there isnt's a language in which deep_copy is implemented
> or whatever and that is simply wrong.
>

I believe what people are generally sceptical about is not whether or not
any language implements an operation called "deep copy", but what *exactly*
that means?  This is completely orthogonal to the specifics of any
language's implementation.  The fact that language X has such a method and
many people use it and many people are happy with it does not address the
questions people are raising.

The claim is that it is not possible to write a truly general and always
correct deep copy operation at the level of a general purpose programming
language.  Writing such an operation absolutely requires an understanding of
the semantics of your objects.  Many people have provided real world
examples that illustrate this claim.

Its not reasonable to expect anyone here to just take your word that
Language X does it correctly.  And if you can't explain how this is possible
in natural language, that is a very strong suggestion that you shouldn't
trust your own word on that either.

Question your assumptions!  That is the True Path to enlightenment!  : )

Coby
--
(remove #\space "coby . beck @ opentechgroup . com")

> > This is a false conclusion.  The indicated action at this point is not
to
> > shut up but just the reverse--to explain in terms people here can
understand
> > how Eiffel manages.  If it can be done, I think people wnat to
understand
> > it.
> I can not discuss in Eiffel terms here. And so I can not "disucss it
> further"
>

PS.  This is an unfair cop-out!
From: Marco Antoniotti
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <y6cy9p5xg3u.fsf@octagon.mrl.nyu.edu>
Your example is interesting,  but, without further knowlegde of
Eiffel, it seems to me that the language is providing a 'clone' method
(feature, whatever) and a 'deep_clone' method.

Now, I do not know what is the semantics of these two methods and I do
not know how the 'deep_copy' can ensure all the constraints that seem
present in the program.

Would you care to explain how in Eiffel all these things are
intertwined?

Cheers

-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
                    "Hello New York! We'll do what we can!"
                           Bill Murray in `Ghostbusters'.
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <87lml446v9.fsf@frown.here>
Marco Antoniotti <·······@cs.nyu.edu> writes:

> Your example is interesting,  but, without further knowlegde of
> Eiffel, it seems to me that the language is providing a 'clone' method
> (feature, whatever) and a 'deep_clone' method.
> 
> Now, I do not know what is the semantics of these two methods and I do
> not know how the 'deep_copy' can ensure all the constraints that seem
> present in the program.
> 
> Would you care to explain how in Eiffel all these things are
> intertwined?
I doubt that is on-topic here. I posted how deep_xxx is specified in
Eiffel. You got a one-to-one copy of an object and all it's fields
(slots, functions etc), so you can not say later (hardly) what the original is
and what the copy is. Assertions are an intergral part of Eiffel,
there behavior in Inheritance is specified and they are the main tool
to express what you expect a class to do. But it does not reveal
anything on how to achieve that.

Assertions and Exceptions go hand in hand in Eiffel but IMHO is the
Condition System of Common Lisp much bette and more elaborate. In fact
I do think the Eiffel Exceptions are somewhat too primitive. But again
that's off-topic here.

Regards
Friedrich
From: Kent M Pitman
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <sfwk80nn730.fsf@world.std.com>
Friedrich Dominicus <·····@q-software-solutions.com> writes:

> Marco Antoniotti <·······@cs.nyu.edu> writes:
> 
> > Your example is interesting,  but, without further knowlegde of
> > Eiffel, it seems to me that the language is providing a 'clone' method
> > (feature, whatever) and a 'deep_clone' method.
> > 
> > Now, I do not know what is the semantics of these two methods and I do
> > not know how the 'deep_copy' can ensure all the constraints that seem
> > present in the program.
> > 
> > Would you care to explain how in Eiffel all these things are
> > intertwined?
>
> I doubt that is on-topic here.

Oh, you might be surprised what some of us regard as on-topic here.
Comparative language topics are well in range--just make sure you 
translate for us "natives".  

> Assertions and Exceptions go hand in hand in Eiffel but IMHO is the
> Condition System of Common Lisp much bette and more elaborate. In fact
> I do think the Eiffel Exceptions are somewhat too primitive. But again
> that's off-topic here.

Well, if you think the CL condition system is better, I suppose there's
no need to proceed.  But if there's some aspect of the Eiffel system,
conditions or otherwise, that you think is better than or interesting to
CL people, I think it's fine to raise it here.
From: Kent M Pitman
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <sfw7kwq68h7.fsf@world.std.com>
Friedrich Dominicus <·····@q-software-solutions.com> writes:

> ... I have a somewhat larger Eiffel program and in it there is
> exactly one deep_copy.  I tried to get away without it but
> unsuccessfull. I do think that a deep_copy is a very useful thing,
> as are other facilites. Too often used it could probably indicate a
> "structural" problem.

I wish I could explain the depths of my pain when I hear the term
"deep copy".  If you think "data rape", you're close.

Being itself semantically meaningless, I can't imagine there could 
possibly be a correct application of it unless in a universe where
the programmer had total world knowledge of the representation of all
objects that could be run through his programmer and was merely saying
"deep copy will in this limited case coincidentally and without damage
satisfy the need for a semantically meaningful copy".  In the presence
of no such total world knowledge and total representational knowledge,
I just don't see how it can ever be meaningful/right.

Please read:

  http://world.std.com/~pitman/PS/EQUAL.html
From: Friedrich Dominicus
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <87vgka4l9d.fsf@frown.here>
Kent M Pitman <······@world.std.com> writes:

> Friedrich Dominicus <·····@q-software-solutions.com> writes:
> 
> > ... I have a somewhat larger Eiffel program and in it there is
> > exactly one deep_copy.  I tried to get away without it but
> > unsuccessfull. I do think that a deep_copy is a very useful thing,
> > as are other facilites. Too often used it could probably indicate a
> > "structural" problem.
> 
> I wish I could explain the depths of my pain when I hear the term
> "deep copy".  If you think "data rape", you're close.
I suggest you read Object oriented software construction and have a
look into either Eiffel and/or Sather. If you can't live with how it
is specified there, now that's up to you. But just because it hurts
you does not mean it does not work.
> 
> Being itself semantically meaningless, I can't imagine there could 
> possibly be a correct application of it unless in a universe where
> the programmer had total world knowledge of the representation of all
> objects that could be run through his programmer and was merely saying
> "deep copy will in this limited case coincidentally and without damage
> satisfy the need for a semantically meaningful copy".  In the presence
> of no such total world knowledge and total representational knowledge,
> I just don't see how it can ever be meaningful/right.
Are you kidding. We are talking about objects. So a compiler should be
able to figure out how a object is constructed.
> 
> Please read:
> 
>   http://world.std.com/~pitman/PS/EQUAL.html
I will look into it, and I suggest you look into OOSC. After that and
after trying Eiffel we can talk about it again.

Regards
Friedrich
From: Frank A. Adrian
Subject: Re: multiple copies of a CLOS object?
Date: 
Message-ID: <3B663C84.100B626C@qwest.net>
Amanda Stent wrote:
> 
> Is there a CLOS function for copying a CLOS object so that you end up with
> two clones that are thereafter independent?
> 
> Thanks in advance.


As many here have told you, no.  However, you could make a clonable
mixin that looked at the metaclass information to do an instantiation
followed by a shallow copy.  This would allow you to do what is done in
many smalltalk implementations:  The generic copy method is a shallow
copy followed by a post copy method.  The post copy method is then
extended to do deeper copies as needed by the object based on its class.
In Lisp it's even easier.  Rather than defining a separate post copy
method, just define an :after method for copy dispatched on the given
object's class.

And, as many have said here, the "copy concept" may be more tricky than
it seems.  Besides the issues of desired copy depth, there are also
issues with objects that hold native resources, pointers to large
structures (which you may prevent from bing GC'ed), and other nefarious
situations.  Be careful that you're doing what you need to and be sure
to do it only where you need to.