assumeSafeAppend and purity

Steven Schveighoffer schveiguy at yahoo.com
Wed Feb 8 06:38:21 PST 2012


On Tue, 07 Feb 2012 00:35:14 -0500, Jonathan M Davis <jmdavisProg at gmx.com>  
wrote:

> On Monday, February 06, 2012 21:40:55 Steven Schveighoffer wrote:
>> I thought of a better solution:
>>
>> pure T[] pureSafeShrink(T)(ref T[] arr, size_t maxLength)
>> {
>>     if(maxLength < arr.length)
>>     {
>>         bool safeToShrink = (arr.capacity == arr.length);
>>         arr = arr[0..maxLength];
>>         if(safeToShrink) arr.assumeSafeAppend(); // must workaround  
>> purity
>> here
>>     }
>>     return arr;
>> }
>>
>> This guarantees that you only affect data you were passed.
>
> Does it really? What if I did this:
>
> auto arr = new int[](63);
> auto saved = arr;
> assert(arr.capacity == 63);
> assert(saved.capacity == 63);
> pureSafeToShrink(arr, 0);
>
> This happens to pass on my computer, though the exact value required for  
> the
> length will probably vary. So, a slice of the data which is now supposed  
> to be
> no longer part of any array still exists.

There is a difference between this and the example given by Vladimir.  In  
Vladimir's example, you are passed an array slice of elements 0-3, but the  
assumeSafeAppend affects element 4.  This violates the spirit of pure  
having no side effects, even if it is technically sound.  I still am  
undecided as to whether assumeSafeAppend should be pure or not.

In this case, the function will only affect array elements that it is  
passed.  The fact that you changed something in data you were passed does  
not violate pure rules.

However, I think my test is too strict, it actually should be arr.capacity  
!= 0.  This means that the array ends at the end of valid data (no valid  
data exists beyond the array).

-Steve


More information about the Digitalmars-d mailing list