February 08, 2012
On Tue, 07 Feb 2012 00:35:14 -0500, Jonathan M Davis <jmdavisProg@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
1 2
Next ›   Last »