The demise of T[new]

Denis Koroskin 2korden at gmail.com
Mon Oct 19 08:12:39 PDT 2009


On Mon, 19 Oct 2009 18:57:45 +0400, Leandro Lucarella <llucax at gmail.com>  
wrote:

> Andrei Alexandrescu, el 18 de octubre a las 20:16 me escribiste:
>> Here's what I wrote to Walter:
>>
>> ====================
>> I'm going to suggest something terrible - let's get rid of T[new]. I
>> know it's difficult to throw away work you've already done, but
>> really things with T[new] start to look like a Pyrrhic victory. Here
>> are some issues:
>>
>> * The abstraction doesn't seem to come off as crisp and clean as we
>> both wanted;
>>
>> * There are efficiency issues, such as the two allocations that you
>> valiantly tried to eliminate in a subset of cases;
>>
>> * Explaining two very similar but subtly different types to
>> newcomers is excruciatingly difficult (I'll send you a draft of the
>> chapter - it looks like a burn victim who didn't make it);
>>
>> * Furthermore, explaining people when to use one vs. the other is
>> much more difficult than it seems. On the surface, it goes like
>> this: "If you need to append stuff, use T[new]. If not, use T[]."
>> Reality is much more subtle. For one thing, T[new] does not allow
>> contraction from the left, whereas T[] does. That puts T[] at an
>> advantage. So if you want to append stuff and also contract from the
>> left, there's nothing our abstractions can help you with.
>
> I think this is getting overcomplicated. I don't see it as complex, I see
> it like this:
>
> 2 types should be provided: array and slice.
>
> array is a *real* type, storing and owning memory, it should be something
> like this (conceptually):
>
> class array(T)
> {
> 	size_t length;
> 	size_t capacity;
> 	T[capacity] elements;
> }
>
> 1) a pure reference type.
> 2) 1 allocation only (interior pointers are not a problem, the GC have to
>    support them anyways).
> 3) easily appendable (capacity field).
>
> slice should be something like this:
>
> struct slice(T)
> {
> 	size_t length;
> 	T* ptr;
> }
>
> 1) a pure value type.
> 2) no allocation at all, *ever*.
> 3) not appendable at all.
> 4) You can change both ptr and length, and you can mutate the elements  
> (if
>    not immutable).
>
> So a slice is a window to peek a chunk of data.
>
> Then you have the syntax. In this discussion, T[new] is array and T[] is
> slice. I find that syntax very confusing. I think it could be even better
> to just put those 2 types in object.d (well, do public imports of those
> 2 types in object.d) and let the people write:
>
> array!T a;
> slice!T s;
>
> The array literals should be immutable chunks of memory in the static
> memory, as ClassInfo.init. The type of [1,2,3] should be, for example,
> slice!(immutable int), so:
> auto s = [1,2,3];
> should create a slice!(immutable int) with length 3 and ptr pointing to
> the static memory where the [1,2,3] was stored (this is what happens with
> strings, right? So no surprises here, they are consistent).
>
> slice.dup should return an array. If you want to just copy the length and
> ptr members, use assignment (it's a value type, remember)?
>
> auto s = [1,2,3];
> auto t = s;
> assert(s.length == t.length);
> assert(s.ptr == t.ptr);
> assert(&s != &t);
>
> Assignment of arrays is just a pointer assignment (is a reference type):
>
> auto a = [1,2,3].dup;
> auto b = a;
> assert(a is b);
>
> array.dup returns another array. array[] returns a slice though (you can
> allow implicit casting from array to slice but I don't see the point as
> array[] is short enough and more explicit). slices should not be
> convertible to arrays (use slice.dup for that).
>
>
> Back to the syntax, I think T[new] is *really* confusing. It tell me
> nothing about the type, it provides the same information as calling it
> it wazzzaaap!T for me. I *really* think it would be better to call it
> array!T. But if we have both types, T[] is not clear anymore that is
> a slice, again, you can't figure that out. So maybe T[] should be used  
> for
> arrays, not slices; if you want some syntax sugar I think T[] is more
> guessable to be an array than a slice, and it would be a little more
> backward compatible. Maybe slices can be T[..], but I'm not sure is clear
> enough, again I think we could live with something more explicit like
> array!T and slice!T. But at least slices should be part of the language,
> because that should be the type of "array literals" (damn! that didn't
> sound right =P).
>
>
> I'm missing something? Why this shouldn't work?
>

That's what was initially planned (except some nuances).

I also think we need a precedent of mapping built-in language type to a  
library type, starting with Array!(T) and Range!(T). We could then map  
V[K] to AArray!(K,V), T? to Nullable!(T) etc.

There is one big issue, though: classes and allocations via 'new' don't  
work with CTFE. I believe this is something that is planned (Walter once  
said that an entire subset of D called SafeD should work with CTFE), but  
it is *very* hard to implement, not feasible in a nearest future for sure.



More information about the Digitalmars-d mailing list