ref returns and properties

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Mon Jan 26 17:14:53 PST 2009


Sergey Gromov wrote:
> Mon, 26 Jan 2009 08:06:05 -0800, Andrei Alexandrescu wrote:
> 
>> Anyhow, here's a simple D example. Consider we define a BigInt type as a 
>> value-type struct: when you copy a BigInt to another, the latter becomes 
>> an independent copy:
>>
>> BigInt a = 100;
>> BigInt b = a;
>> ++b;
>> assert(a == 100);
>>
>> BigInt's copy constructor would allocate memory dynamically, which means 
>> it may throw and also that it is inefficient to copy BigInt objects 
>> unwittingly.
>>
>> So far, so good. Now say we define some range that iterates over 
>> BigInts. If that range chooses to implement head() as a property, then a 
>> copy is created whenever you ask for head. The small problem is that 
>> that's inefficient. The larger problem is that there is no way to 
>> correctly e.g. sort such a range. Sorting hinges on swap, and with 
>> properties you can't ever swap without risking to throw. Sort would end 
>> up throwing, and not only throwing, but losing state irretrievably while 
>> at it. Well that's not a foundation we want to build D on, do we?
> 
> This will happen in C++, too, if operator*() decides to throw.
> Algorithms are correct only if objects they manipulate obey the rules.

Of course. The problem with get and set is not that they make it 
possible to write incorrect code. They make it impossible to write 
correct code.

> It seems like your rule is, 'forward ranges are nothrow.'  Any senior
> ranges included.  Or maybe throwing next() or empty() are less
> dangerous?

Yes, because even if they throw, net loss of state is still avoidable.


Andrei



More information about the Digitalmars-d mailing list