Page 1 of 1

Deep copy and shallow copy

PostPosted: Sun Aug 03, 2008 3:21 am
by relez
How is "copy" implemented in Cobra? Of course, you need an example: C#

Code: Select all
 
   1:  struct Example
   2:  {
   3:      public int a;
   4:      public int[] v;
   5:  }
   6:  Example StruA, StruB;
   7:  StruA.a = 10;
   8:  StruA.v = new int[3] { 10, 20, 30 };
   9:  StruB = StruA;


It's interesting that the array is pointed by reference using that code, so every change is reflected both on StrutA and StrutB. By default, if i'm not wrong, we have only a shallow copy. We need manually implement a deep copy. And if we use Cobra?

Re: Deep copy and shallow copy

PostPosted: Tue Aug 05, 2008 10:07 pm
by Charles
Cobra has the same semantics. So in "structB = structA" you're effectively copying the bits from A to B. That means for references you are getting a shallow copy and as you pointed out, a deep copy must be explicit.

C# 2.0+ does have a way to "inline" the array contents with fixed size buffers. The explanation there doesn't start out saying that this only works in "unsafe" code regions, but it ends with a lot of comments about unsafe code. I haven't tried it out, so I'm not sure if this feature is only for unsafe code.

I've played around with the idea of providing a deep copy capability in Cobra, whether via language or library, but didn't spend much time on it. If I recall correctly, Smalltalk had both .deepCopy and .shallowCopy, but it was the responsibility of subclasses to override .deepCopy to "do the right thing". The fact that they provided both methods, however, made for nice organization, convention, and readability.

I have not yet seen a deep copy in any language that was automated, comprehensive, always correct and always desirable. In other words, it's not always obvious which references should be copied or not. Often if an object has a "back reference" to a "parent object", you're not expecting that parent to be copied. And needs could even change based on the application.

Note that one .NET technique for a deep copy is to serialize the object and deserialize it. Although I imagine that is very expensive. Also, you can customize serialization if you want certain fields--like back references--left out.

Another idea is to flag the various properties and/or vars of the object with attributes which are then paid attention to by a copy mechanism.

You could do the things above today with library code if you wanted. They don't require more language features. If you want a .deepCopy on Object you could write:
extend Object
def deepCopy as dynamic
return CopyTool.copy(this)


This is a good time to mention that I expect at some point to provide a "same" type which can be used for return types and argument types. It's short for "same type as receiver". Then you could have "def deepCopy as same" and still have strong, accurate typing.