ref returns and properties

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sun Jan 25 07:35:10 PST 2009


I realized that properties are not a complete model for actual data. The 
current conventional wisdom about properties goes like this (T is some 
type):

class Host
{
     property prop
     {
         T get() { ... }
         void set(T value) { ... }
     }
}

If T is e.g. an int, it all works nicely. Now consider T is a 
highly-structured piece of data that holds resources. In that case we 
want to make sure T is not copied unwittingly such that the resource is 
managed properly. This means that T has a copy constructor and a destructor.

For such cases, extensive experience with C++ has shown that two 
primitives are essential: move and swap.

void move(ref T src, ref T dst);
void swap(ref T lhs, ref T rhs);

Move takes the guts of src, puts them in dst, and then clears src 
effectively relieving it from any resource. Swap exchanges the guts of 
src and dst without any extra resource copying.

Now if "prop" were a classic data, swapping host1.prop and host2.prop is 
a piece of cake (that is realized inside std.algorithm. Look it up, the 
implementation has quite a few interesting quirks!)

But if "prop" is a property with get and set, everything falls apart. 
Properties effectively hide the address of the actual data and only 
traffic in values. That's often good (and sometimes even the only 
possibility in the case of properties computed on-the-fly), but this 
abstraction effectively makes resource-conserving move and swap impossible.

I noticed this problem when dealing with ranges. The .head() function, 
if it returns a value, cannot be swapped/moved. Same applies to opIndex 
when implemented as a value property (via the opIndex/opIndexAssign tandem).

What to do? I'd like to refine the notion of property such that moving 
properties around is possible, without, however, complicating their 
interface too much.


Andrei



More information about the Digitalmars-d mailing list