www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - .clone()

reply Florian RIVOAL <Florian_member pathlink.com> writes:
hummm... I wonder if this is already available and i just didn't see what's the
correct syntax to do it, or if it is just plain missing.

since all object are held by reference, there might be some times when you want
to copy them. And if the object it self holds references to other object, in
depth copy could be usefull. While there is no special difficulty to do it case
by case, it seems to me there is no general way to do it. As i see it, the
following stuff would be usefull:

* a "Object clone()" method in the Object class.
* a .clone property on arrays, behaving like this :
- indentical to .dup for arrays of basic types
- call .clone on all elements for array of array
- call clone() on all elements for arrays of objects

So is it there already under a different form?
if not, is there a good reason why it is not there?
Jul 13 2004
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
walter does not like shallow copies, and thus "deep" copies are built into
the language :)

class A
{
 int x;
}

void main()
{
 A a=new A;
 A b=a;
 printf("%x\n%x\n",&a,&b);
}

this prints the addressess of a and b.  clearly they are different, but b
now has the same *data* as a.  i love this feature :)
Jul 13 2004
parent reply J Anderson <REMOVEanderson badmama.com.au> writes:
Jarrett Billingsley wrote:

walter does not like shallow copies, and thus "deep" copies are built into
the language :)

class A
{
 int x;
}

void main()
{
 A a=new A;
 A b=a;
 printf("%x\n%x\n",&a,&b);
}

this prints the addressess of a and b.  clearly they are different, but b
now has the same *data* as a.  i love this feature :)

  

is not a deep copy, that is a reference (or pointer) copy. D does not support shallow or deep copies for classes, although it does support shallow copies for structs. Take a gaze at this: class A { int x; } void main() { A a=new A; a.x = 10; A b=a; b.x = 11; printf("%d\n%d\n",a.x,b.x); //What is the result? } -- -Anderson: http://badmama.com.au/~anderson/
Jul 13 2004
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
 I'm tempted to say - what the hell are you on about

go ahead, say it :( i forgot about that hidden level of abstraction in there. thus the pointers are different but each point to the same thing.
Jul 13 2004
prev sibling next sibling parent J Anderson <REMOVEanderson badmama.com.au> writes:
Florian RIVOAL wrote:

hummm... I wonder if this is already available and i just didn't see what's the
correct syntax to do it, or if it is just plain missing.

since all object are held by reference, there might be some times when you want
to copy them. And if the object it self holds references to other object, in
depth copy could be usefull. While there is no special difficulty to do it case
by case, it seems to me there is no general way to do it. As i see it, the
following stuff would be usefull:

* a "Object clone()" method in the Object class.
* a .clone property on arrays, behaving like this :
- indentical to .dup for arrays of basic types
- call .clone on all elements for array of array
- call clone() on all elements for arrays of objects

So is it there already under a different form?
if not, is there a good reason why it is not there?


  

I brought this up before. I think it should be done by some standard interfaces (or abstract classes -> which allow auto-up-casting). For automatic support, things would be easier when property RTTI comes in to D (fingers crossed for 2.0). -- -Anderson: http://badmama.com.au/~anderson/
Jul 13 2004
prev sibling next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Florian RIVOAL wrote:

<snip>
 since all object are held by reference, there might be some times when you want
 to copy them. And if the object it self holds references to other object, in
 depth copy could be usefull.

For certain applications, such as duplicating a tree structure where there's a reason to do so. But I'm not sure that it's useful enough in general.
 While there is no special difficulty to do it case
 by case, it seems to me there is no general way to do it. As i see it, the
 following stuff would be usefull:
 
 * a "Object clone()" method in the Object class.
 * a .clone property on arrays, behaving like this :
 - indentical to .dup for arrays of basic types
 - call .clone on all elements for array of array
 - call clone() on all elements for arrays of objects
 
 So is it there already under a different form?
 if not, is there a good reason why it is not there?

What would Object.clone do? (a) a memberwise shallow copy? (b) a memberwise deep copy, at the risk of running into a circular structure and taking up infinite time and memory? (c) just return this, enabling the class designer to override it to actually copy? If we chose (a) or (b), then class designers would need to override it if cloning the class makes no sense. This goes against the principle that subclasses are supposed to extend functionality, not remove it. This leaves (c), a safe default behaviour, which also enables arrays of objects to be cloned as deeply as allowed by the classes involved. But it also brings us back to the issue of the class designer forgetting to add new fields to the clone method, unless we give some kind of controlled access to built-in 'memberwise shallow copy' and 'memberwise clone' statements. Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 13 2004
parent reply pragma <EricAnderton at yahoo dot com> <pragma_member pathlink.com> writes:
In article <cd168g$v4b$1 digitaldaemon.com>, Stewart Gordon says...
What would Object.clone do?

(a) a memberwise shallow copy?
(b) a memberwise deep copy, at the risk of running into a circular 
structure and taking up infinite time and memory?
(c) just return this, enabling the class designer to override it to 
actually copy?

Here's my $0.02. :) There are plenty of reasons why you don't want to have a platform/language default to a deep copy for structs and classes. Circular structures (as you mentioned above) are just one example. Classes that aren't threadsafe, and protect fields via method access are another. You might not want to duplicate exceptionally deep trees and other huge data structures due to memory/cache issues. Arcane Jill has also mentioned in this NG the implications of not having explicit memory control when writing very-secure applications. Not being able to guard any member against a deep .clone() operation would be disasterous to such applications IMO. The best compromise would be something like (C): to have Object.clone default to a shallow copy, much like .dup() does for arrays. Actually, .dup() should probably be used for objects too for language consistency. If need be, clone()/.dup() can then be overridden to return anything the implementor wants: this, null, an uninitalized struct/class, or even throw an exception if the operation is not allowed. - Pragma
Jul 13 2004
next sibling parent Florian RIVOAL <Florian_member pathlink.com> writes:
In article <cd185b$12lr$1 digitaldaemon.com>, pragma <EricAnderton at yahoo dot
com> says...
In article <cd168g$v4b$1 digitaldaemon.com>, Stewart Gordon says...
What would Object.clone do?

(a) a memberwise shallow copy?
(b) a memberwise deep copy, at the risk of running into a circular 
structure and taking up infinite time and memory?
(c) just return this, enabling the class designer to override it to 
actually copy?

Here's my $0.02. :) There are plenty of reasons why you don't want to have a platform/language default to a deep copy for structs and classes. Circular structures (as you mentioned above) are just one example. Classes that aren't threadsafe, and protect fields via method access are another. You might not want to duplicate exceptionally deep trees and other huge data structures due to memory/cache issues. Arcane Jill has also mentioned in this NG the implications of not having explicit memory control when writing very-secure applications. Not being able to guard any member against a deep .clone() operation would be disasterous to such applications IMO. The best compromise would be something like (C): to have Object.clone default to a shallow copy, much like .dup() does for arrays. Actually, .dup() should probably be used for objects too for language consistency. If need be, clone()/.dup() can then be overridden to return anything the implementor wants: this, null, an uninitalized struct/class, or even throw an exception if the operation is not allowed. - Pragma

Jul 13 2004
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
pragma <EricAnderton at yahoo dot com> wrote:
<snip>
 The best compromise would be something like (C): to have Object.clone 
 default to a shallow copy, much like .dup() does for arrays.  
 Actually, .dup() should probably be used for objects too for language 
 consistency.

Actually, we should be careful to distinguish between .dup (a shallow copy, by definition) and .clone (a deep copy, or as deep as allowed). But yes, clone would _default_ to a shallow copy at the most. If we're going to have shallow object copies as a default behaviour, then we might as well define it in Object.dup, and have Object.clone simply call this method. We'd need clear documentation of the contractual difference between them.
 If need be, clone()/.dup() can then be overridden to return anything 
 the implementor wants: this, null, an uninitalized struct/class, or 
 even throw an exception if the operation is not allowed.

I don't see any point in making this a disallowed operation. If copying the object doesn't make sense for whatever class, we might as well copy the reference instead. Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 14 2004
next sibling parent reply Florian RIVOAL <Florian_member pathlink.com> writes:
 If need be, clone()/.dup() can then be overridden to return anything 
 the implementor wants: this, null, an uninitalized struct/class, or 
 even throw an exception if the operation is not allowed.

I don't see any point in making this a disallowed operation. If copying the object doesn't make sense for whatever class, we might as well copy the reference instead.

Not sure either, but ask the guys at working for sun, they might have an idea, since java includes this behaviour : it throws an exception if you try to clone something without explicit mention it is clonable.
Jul 14 2004
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Florian RIVOAL wrote:

 If need be, clone()/.dup() can then be overridden to return 
 anything the implementor wants: this, null, an uninitalized 
 struct/class, or even throw an exception if the operation is not 
 allowed.

I don't see any point in making this a disallowed operation. If copying the object doesn't make sense for whatever class, we might as well copy the reference instead.

Not sure either, but ask the guys at working for sun, they might have an idea, since java includes this behaviour : it throws an exception if you try to clone something without explicit mention it is clonable.

Java has the Cloneable interface. The default behaviour of objects that implement Cloneable is a shallow memberwise copy. Classes are allowed to override clone pretty much how they like. However, with Java data structures tending to accommodate arbitrary objects, you can't guarantee non-circularity. If you could, a typical behaviour would perhaps be to see if each element instanceof Cloneable, and if so then clone it, otherwise copy the reference. That's indeed what would happen with behaviour (c) I suggested. D is a different kettle of fish, as it has templates* and so little need to declare data structures taking arbitrary combinations of objects. But still, there is some caution to be taken. *OK, so Java has recently added them so I've heard, but plenty of legacy code is around using the Object structures.... Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 14 2004
prev sibling next sibling parent reply pragma <EricAnderton at yahoo dot com> <pragma_member pathlink.com> writes:
In article <cd2v1k$14m1$1 digitaldaemon.com>, Stewart Gordon says...
pragma <EricAnderton at yahoo dot com> wrote:
<snip>
 The best compromise would be something like (C): to have Object.clone 
 default to a shallow copy, much like .dup() does for arrays.  
 Actually, .dup() should probably be used for objects too for language 
 consistency.

Actually, we should be careful to distinguish between .dup (a shallow copy, by definition) and .clone (a deep copy, or as deep as allowed). But yes, clone would _default_ to a shallow copy at the most. If we're going to have shallow object copies as a default behaviour, then we might as well define it in Object.dup, and have Object.clone simply call this method. We'd need clear documentation of the contractual difference between them.

I see what you're saying by wanting to have mulitple ways to manipulate object cloning. It makes sense to have multiple methods for multiple needs (.dup vs clone). My question is: what would be the major differences/pros/cons between having dup and .clone defined side-by-side in Object instead of just having one or the other? If a class implementor were to just override the given method to give the behavior they want, then that's less trouble right?
 class MySingleton{
     static MySingleton _instance;
     static this(){
         _instance = new MySingleton();
     }
     // override one method to get the job done!
     void* opDup(){ 
         // side-step duplication by returning the instance instead
         return _instance; 
     }
 }

('opDup' is contrived of course.. it could easily be 'dup' or something else) If there are fewer places where a given behavior exists, then it should be easier to maintain and hence less buggy. If the behavior of .dup and .clone are nearly identical, then maybe its better for bug control to make them the same method. IMO, if someone needs a more specialized kind of copying mechanism, then that should go in a specialised interface/class instead of on "Object"... especially if everyone else isn't going to need it.
 If need be, clone()/.dup() can then be overridden to return anything 
 the implementor wants: this, null, an uninitalized struct/class, or 
 even throw an exception if the operation is not allowed.

I don't see any point in making this a disallowed operation. If copying the object doesn't make sense for whatever class, we might as well copy the reference instead.

I agree that returing 'this' or a reference is probably the best default behavior possible. When I said "event throw an exception..." I was just thinking aloud with some examples of how overriding duplicate/clone freely would give a developer all the flexibility they needed. In my example above (MySingleton), I could just as easily put an 'assert' or 'throw' in there to prevent an *attempt* in duplication as to discourage its use completely... but that's just an example. I'm really glad this topic came along. C++ handles this kind of thing poorly and Java does a little better with use of ICloneable. Since duplication in D is built-into all the primitive types (arrays), why not make it a standard feature of objects and structs? Makes sense to me. - Pragma
Jul 14 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
pragma <EricAnderton at yahoo dot com> wrote:
<snip>
     // override one method to get the job done!
     void* opDup(){ 
         // side-step duplication by returning the instance instead
         return _instance; 
     }
 }

('opDup' is contrived of course.. it could easily be 'dup' or something else)

If arrays are anything to go by, then the 'standard' name already is dup, and it returns an object of the same type, not a void*.
 If there are fewer places where a given behavior exists, then it 
 should be easier to maintain and hence less buggy.

I see little room for bugs in a function like Object clone() { return dup(); }
 If the behavior of .dup and .clone are nearly identical, then maybe 
 its better for bug control to make them the same method.

Any half-decent compiler would inline the above so that they become the same method. <snip>
 I don't see any point in making this a disallowed operation.  If 
 copying the object doesn't make sense for whatever class, we might 
 as well copy the reference instead.

I agree that returing 'this' or a reference is probably the best default behavior possible.

this already is a reference. What other kind of reference would we return? Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 14 2004
parent reply pragma <EricAnderton at yahoo dot com> <pragma_member pathlink.com> writes:
In article <cd3jb9$26j4$1 digitaldaemon.com>, Stewart Gordon says...
 If there are fewer places where a given behavior exists, then it 
 should be easier to maintain and hence less buggy.

I see little room for bugs in a function like Object clone() { return dup(); }

True enough. But now we really have two methods for the same basic operation by default. That doesn't seem useful to me. I suppose if clone were the only one of the two that is overridable that would be better, but then you still cannot stop clones from being generated through dup. One point of access solves more problems than two, IMO.
 If the behavior of .dup and .clone are nearly identical, then maybe 
 its better for bug control to make them the same method.

Any half-decent compiler would inline the above so that they become the same method.

Accept if the're overridable, in which case you're looking into the v-table and cannot optimize it away.
<snip>
 I don't see any point in making this a disallowed operation.  If 
 copying the object doesn't make sense for whatever class, we might 
 as well copy the reference instead.

I agree that returing 'this' or a reference is probably the best default behavior possible.

this already is a reference. What other kind of reference would we return?

Oops, should've checked that one before hitting 'post'... you're right, it would be just plain 'ol 'this' by default as you suggested. :) - Pragma
Jul 14 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
pragma <EricAnderton at yahoo dot com> wrote:

<snip>
 True enough.  But now we really have two methods for the same basic 
 operation by default.  That doesn't seem useful to me.  I suppose if 
 clone were the only one of the two that is overridable that would be 
 better, but then you still cannot stop clones from being generated 
 through dup.  One point of access solves more problems than two, IMO.

The point is that it enables a class to support two kinds of copy: deep and shallow. The call to dup serves as a point at which the depth will stop, perhaps because that's where non-circularity can no longer be guaranteed, or because you reach a point at which no further depth can possibly exist. A class that serves as a data structure can override dup in order to create a copy of the whole structure, but not clone the individual elements. OTOH, it could override clone enabling the individual elements to be cloned as well. Giving the class user the choice is a possible generic programming advantage. <snip>
 Accept

Pardon?
 if the're overridable, in which case you're looking into the 
 v-table and cannot optimize it away.

It can if the compiler determines that it isn't overridden anywhere below the type in which it is called. Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 14 2004
next sibling parent reply pragma <EricAnderton at yahoo dot com> <pragma_member pathlink.com> writes:
In article <cd3oqo$2g0j$1 digitaldaemon.com>, Stewart Gordon says...
The point is that it enables a class to support two kinds of copy: deep 
and shallow.  The call to dup serves as a point at which the depth will 
stop, perhaps because that's where non-circularity can no longer be 
guaranteed, or because you reach a point at which no further depth can 
possibly exist.

A class that serves as a data structure can override dup in order to 
create a copy of the whole structure, but not clone the individual 
elements.  OTOH, it could override clone enabling the individual 
elements to be cloned as well.  Giving the class user the choice is a 
possible generic programming advantage.

Stewart, I'm glad you put it this way, as I think I understand now. And you're right: it does give a lot of flexibility when the differences between .dup and .clone are well-defined. I'm going to stick to my own opinion on this one, but I *do* see the merit in this design. They just don't feel orthogonal enough to me. Perhaps there's a compromise waiting for us down the road? :)
<snip>
 Accept

Pardon?

::shrug:: I have no idea. Is it time for me to reinstall win2k already? ;)
 if the're overridable, in which case you're looking into the 
 v-table and cannot optimize it away.

It can if the compiler determines that it isn't overridden anywhere below the type in which it is called.

Do you mean if the compiler knows if a given class is subclassed anywhere? I don't think that's possible. - Pragma
Jul 14 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
pragma <EricAnderton at yahoo dot com> wrote:

<snip>
 if the're overridable, in which case you're looking into the 
 v-table and cannot optimize it away.

<snip> It can if the compiler determines that it isn't overridden anywhere below the type in which it is called.

Do you mean if the compiler knows if a given class is subclassed anywhere? I don't think that's possible.

Of course it can. Look at the class hierarchy to see if there are any subclasses, and then to see if any of them can ever be instantiated in the course of the program. This is one of the optimisation principles on which D was designed. See http://www.digitalmars.com/d/function.html However, it does require the modules to be compiled all in one go.... Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 16 2004
parent reply "Matthew Wilson" <admin.hat stlsoft.dot.org> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
news:cd89ef$383$1 digitaldaemon.com...
 pragma <EricAnderton at yahoo dot com> wrote:

 <snip>
 if the're overridable, in which case you're looking into the
 v-table and cannot optimize it away.

<snip> It can if the compiler determines that it isn't overridden anywhere below the type in which it is called.

Do you mean if the compiler knows if a given class is subclassed


 don't think that's possible.

Of course it can. Look at the class hierarchy to see if there are any subclasses, and then to see if any of them can ever be instantiated in the course of the program. This is one of the optimisation principles on which D was designed. See http://www.digitalmars.com/d/function.html However, it does require the modules to be compiled all in one go....

This precludes any dynamic loading of classes, then. I know that this is a 2.x feature, at best, but it's still probably good to consider.
Jul 16 2004
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Matthew Wilson wrote:

<snip>
 This precludes any dynamic loading of classes, then.

Only if this feature is actually used in a given program.
 I know that this is a 2.x feature, at best, but it's still probably 
 good to consider.

I'd no idea that this was planned. But I can't see it working well with a compiled OO model, perhaps unless some superclass is specified at compile time, and access to the dynamically loaded class from outside is restricted to members of that superclass. In that case, only those methods of those superclasses need be made virtual for the sake of dynamic loading. Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 16 2004
prev sibling parent Florian RIVOAL <Florian_member pathlink.com> writes:
The point is that it enables a class to support two kinds of copy: deep 
and shallow.  The call to dup serves as a point at which the depth will 
stop, perhaps because that's where non-circularity can no longer be 
guaranteed, or because you reach a point at which no further depth can 
possibly exist.

A class that serves as a data structure can override dup in order to 
create a copy of the whole structure, but not clone the individual 
elements.  OTOH, it could override clone enabling the individual 
elements to be cloned as well.  Giving the class user the choice is a 
possible generic programming advantage.

I totaly agree with this way of doing things. I already can't wait to see it implemented. But i am skipping some steps. Before thinking of seeing added to D, it seems quite reasonable to ask Walter what he thinks about this matter. So, Walter, any opinion on .dup, .clone and the like?
Jul 15 2004
prev sibling parent Regan Heath <regan netwin.co.nz> writes:
On Wed, 14 Jul 2004 10:40:03 +0100, Stewart Gordon <smjg_1998 yahoo.com> 
wrote:
 pragma <EricAnderton at yahoo dot com> wrote:
 <snip>
 The best compromise would be something like (C): to have Object.clone 
 default to a shallow copy, much like .dup() does for arrays.  Actually, 
 .dup() should probably be used for objects too for language consistency.

Actually, we should be careful to distinguish between .dup (a shallow copy, by definition) and .clone (a deep copy, or as deep as allowed). But yes, clone would _default_ to a shallow copy at the most. If we're going to have shallow object copies as a default behaviour, then we might as well define it in Object.dup, and have Object.clone simply call this method. We'd need clear documentation of the contractual difference between them.
 If need be, clone()/.dup() can then be overridden to return anything 
 the implementor wants: this, null, an uninitalized struct/class, or 
 even throw an exception if the operation is not allowed.

I don't see any point in making this a disallowed operation. If copying the object doesn't make sense for whatever class, we might as well copy the reference instead.

Isn't dup a deep copy currently? eg. char[] p = "regan"; char[] s; s = p //shallow copy p and s refer to same data s = p.dup //deep copy, p and s refer to different data assuming this, then when you write a struct or class you can simply define a 'dup' member and get both shallow and deep copying, right? import std.c.stdlib; extern (C) { void *memcpy( void *dest, void *src, size_t count); } struct A { void* pdata = null; uint plen = 0; void set(char[] _data) { *this = A.init; if (!(_data is null)) { pdata = cast(void*)_data; plen = _data.length; } } A dup() { A a; a.pdata = malloc(plen); memcpy(a.pdata,pdata,plen); return a; } } class B { A a; this(char[] _a = null) { a.set(_a); } B dup() { B b = new B(); b.a = a.dup; return b; } } void main() { char[] data = "regan"; A aa; A ab; B ba = new B(data); B bb = new B(); aa.set(data); ab = aa; //shallow copy printf("A %08x %08x\n",aa.pdata,ab.pdata); ab = aa.dup; //deep copy printf("A %08x %08x\n",aa.pdata,ab.pdata); bb = ba; //shallow copy printf("B %08x %08x\n",ba.a.pdata,bb.a.pdata); bb = ba.dup; //deep copy printf("B %08x %08x\n",ba.a.pdata,bb.a.pdata); } Object could have a default dup' method that asserted or threw an exception. Basic types i.e. int could have a dup method added to them that simply returned themselves. Thus for any object you could call the dup method to do a deep copy, and for any object you could do a shallow copy simply by assigning it. Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jul 14 2004
prev sibling next sibling parent Andy Friesen <andy ikagames.com> writes:
Florian RIVOAL wrote:

 hummm... I wonder if this is already available and i just didn't see what's the
 correct syntax to do it, or if it is just plain missing.
 
 since all object are held by reference, there might be some times when you want
 to copy them. And if the object it self holds references to other object, in
 depth copy could be usefull. While there is no special difficulty to do it case
 by case, it seems to me there is no general way to do it. As i see it, the
 following stuff would be usefull:
 
 * a "Object clone()" method in the Object class.
 * a .clone property on arrays, behaving like this :
 - indentical to .dup for arrays of basic types
 - call .clone on all elements for array of array
 - call clone() on all elements for arrays of objects
 
 So is it there already under a different form?
 if not, is there a good reason why it is not there?

erg. The problem is that subtracting behaviours from classes doesn't work. The best you can get is to do what Java does and throw an exception when some "un-inherited" method is called. Second, loading more stuff into the Object class means loading more baggage into every object created anywhere, even if all it ever does is throw an AssertionFailure. -- andy
Jul 14 2004
prev sibling parent "Matthew Wilson" <admin.hat stlsoft.dot.org> writes:
Guys

I confess I've not followed much of this thread, but I've just had cause to
make a clone() method, in the ranges in DTL. Its semantic is that a range
instance is created that has the same enumeration state as its receiver.
Whether this is deep or shallow is dependent on the specifics of the range
class - it's the enumeration state that's important.

Does this tally with your opinions?
Jul 16 2004