The great slice debate -- should slices be separated from arrays?
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Tue Nov 24 11:55:55 PST 2009
Steven Schveighoffer wrote:
> On Tue, 24 Nov 2009 14:07:27 -0500, Andrei Alexandrescu
> <SeeWebsiteForEmail at erdani.org> wrote:
>
>> Steven Schveighoffer wrote:
>>> On Tue, 24 Nov 2009 11:07:43 -0500, Andrei Alexandrescu
>>> <SeeWebsiteForEmail at erdani.org> wrote:
>>>
>>>> Steven Schveighoffer wrote:
>>>>> In many other posts, people have been festering over dropping
>>>>> T[new] and not having a reference array type. The argument is (and
>>>>> forgive me if this is a strawman, someone from the other side can
>>>>> post if I'm incorrect): If we make arrays a separate type from
>>>>> slices, and only allow appending on arrays, then we solve the
>>>>> stomping problem and the hard-to-determine reallocating problem.
>>>>> For those who are unfamiliar with these problems, I'll try to
>>>>> outline them at the bottom of the post.
>>>>> I contend that even if we make arrays a separate type, even if
>>>>> arrays are made a true reference type, slices will still suffer
>>>>> from the same hard-to-determine reallocation problem *unless* we
>>>>> make slices fatter.
>>>>> My proof is as simple as an example. Assume 'Array' is the new
>>>>> type for an array:
>>>>> auto a = new Array!(int)(15); // allocate an array of 15 integers,
>>>>> all 0
>>>>> auto s = a[0..5];
>>>>> a ~= [1,2,3,4,5];
>>>>> a[0] = 1.
>>>>> Now, what does s[0] equal?
>>>>
>>>> Array may include a field
>>>>
>>>> bool sliceExtracted;
>>>>
>>>> that is set to true whenever you take a slice from the array and set
>>>> to false whenever the array's data is reallocated. The array's
>>>> documentation could mention that ~= is amortized constant if there
>>>> are no intervening slicing operations.
>>> We weren't talking about performance, but I think I know what you
>>> are saying: To solve the hard-to-determine reallocation problem, you
>>> propose that any array which has had a slice taken from it, will
>>> reallocate on append even if it could grow into the block? That
>>> seems like a rather blunt solution...
>>> if(arr[0.."hello".length] == "hello")
>>> arr ~= "xyz"; // oops, reallocate because we took a slice earlier.
>>> Wouldn't this make slicing combined with appending unusable for
>>> performance reasons? Then the only time you want to use slices is if
>>> you are done appending to the array, and then even today's
>>> implementation wouldn't cause the hard-to-determine problem for code
>>> written that way.
>>> Maybe I misunderstood you, let me know.
>>
>> You understood me correctly. I think it's reasonable if Array defines
>> ~= in relation to using other primitives. It's a common approach, for
>> example, in C++ and Java to define an operation (such as bumping or
>> dereferencing an iterator) in terms of no intervening conflicting
>> operations against the same object.
>
> Why do we need this scheme then? If it only makes sense to use slicing
> when you are done appending, then why not use that model with today's
> rules? Why make code that uses slices before you are finished appending
> perform poorly? Why make code that uses temporary slices (like I showed
> in my example) perform poorly?
Because we don't know how to make things perfect in all circumstances.
Andrei
More information about the Digitalmars-d
mailing list