The demise of T[new]

Leandro Lucarella llucax at gmail.com
Mon Oct 19 07:57:45 PDT 2009


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?

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
- Que hacés, ratita?
- Espero un ratito...



More information about the Digitalmars-d mailing list