T[new]
Steven Schveighoffer
schveiguy at yahoo.com
Mon Aug 10 12:38:40 PDT 2009
On Mon, 10 Aug 2009 15:21:48 -0400, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> wrote:
> Steven Schveighoffer wrote:
>> On Mon, 10 Aug 2009 14:38:24 -0400, Stewart Gordon
>> <smjg_1998 at yahoo.com> wrote:
>>
>>> Since nobody's yet asked....
>>>
>>> What type would .dup and .idup return?
>>>
>>> The best choice I can see is to make .dup return T[new] and .idup
>>> return invariant(T)[].
>> This brings up another question. Should something like
>> immutable(T)[new] or const(T)[new] be even valid? Consider this:
>> immutable(char)[new] str = "hello".idup; // not sure how you convert a
>> literal to an array, but assume it works for now.
>> assert(str.capacity == 16); // assume GC still allocates 16 minimum
>> blocks
>> str ~= " there";
>> auto slice = str[5..$];
>> str.length = 5;
>> str ~= " world";
>> assert(slice == " there"); // fails?
>> We most likely have the same issue here with immutable data as we do
>> today, just not as obvious. Although it's a corner case, it does
>> violate immutability without casts.
>> There are several options:
>> 1. immutable(T)[new] and const(T)[new] are invalid. This limits us
>> more than the current regime, but is a questionable construct to begin
>> with, considering it allows appending in place (you can always create a
>> new array with concatenation).
>> 2. immutable(T)[new] and const(T)[new] are equivalent to
>> immutable(T[new]) and const(T[new]) respectively. This simplifies
>> generic programming and still prevents abuses.
>> 3. when you shrink an array of immutable/const elements' length, the
>> capacity automatically shrinks to prevent overwriting previous data.
>> This still leaves mutable data with the overwrite problem, but it
>> doesn't violate const.
>> 4. same as #3 but do it for both immutable or mutable arrays.
>> Also, implicit casting to const needs to be addressed, normally you
>> can't do this with templated types (if that's how the underlying type
>> is implemented).
>
> I think 1 is a good option. Essentially you can't have a resizeable
> array of immutable data. Functional languages don't have such a thing.
> If we go for (3), code that looks tighter is in fact more wasteful as
> every shrinking+expanding cycle causes a new allocation and a copy.
Consider this then:
template ArrayOf(T)
{
alias T[new] ArrayOf;
}
Is ArrayOf!invariant(char) valid? Should it be? I'm not sure, this was
my focus of option 2.
-Steve
More information about the Digitalmars-d
mailing list