The demise of T[new]

dsimcha dsimcha at yahoo.com
Sun Oct 18 17:51:37 PDT 2009


== Quote from Andrei Alexandrescu (SeeWebsiteForEmail at erdani.org)'s article
> > 3.  A T[new] should be implicitly convertible to a slice.  For example:
> >
> > auto foo = someFunctionThatReturnsTnew();
> > // foo is a T[new].
> > T[] bar = someFunctionThatReturnsTnew();
> > // Works.  bar is a T[].  The T[new] went into oblivion.
> >
> > This solves the problem of slices not being closed over .dup and ~.
> Check.

So then why is slices not being closed over .dup, ~, etc. still a problem?  With
implicit conversion, they for all practical purposes are.

> > 4.  It should be guaranteed that no block of memory is ever referenced by more
> > than one T[new] instance.  This is needed to guarantee safety when appending to
> > immutable arrays, etc.
> That doesn't go with reference semantics. Uncheck.
> > 5.  Assigning a T[new] to another T[new] should be by reference, just like
> > assigning a class instance to another class instance.
> Check. (BTW contradicts 4)

There was a slight misunderstanding here.  When I say an instance, I mean one
T[new] heap object == one instance, no matter how many pointers/references to this
instance you have.  The assumption is that T[new] objects live entirely on the
heap and have semantics similar to classes.  For example:

uint[new] foo = new uint[100];
uint[new] bar = foo;  // Really just a pointer assignment.

Now, both foo and bar point to the same uint[new] instance.  If anything is
modified via foo, it is seen when viewed from bar and vice-versa.

To clarify, no *main block of memory that holds the data in the array* is ever
referenced by more than one T[new] *heap object*.

> > Assigning a T[] to a T[new]
> > should duplicate the memory block referenced by the T[] because this is probably
> > the only way to guarantee (4).
> No check, but could have been done.

Actually, this can even be done by COW.  Initially, assigning a T[] to a T[new]
could just be a pointer assignment and setting a flag, as long as a copy of the
data is made when you try to increase the length of the T[new] or append to it.
Basically, as long as you use the T[new] as if it were a T[], no copying needs to
be done.

> > 6.  Since T[new] guarantees unique access to a memory block, it should have an
> > assumeUnique() method that returns an immutable slice and sets the T[new]'s
> > reference to the memory block to null.  This solves the problem of building
> > immutable arrays without the performance penalty of not being able to pre-allocate
> > or the unsafeness of having to cowboy cast it to immutable.
> Uncheck.

Now that I've explained my uniqueness thing better, does this sound feasible?

> > 7.  As long as the GC is conservative, there absolutely *must* be a method of
> > manually freeing the memory block referenced by a T[new] provided that the GC
> > supports this operation, though it doesn't have to be particularly pretty.  In
> > general, since D is a systems language, T[new] should not be too opaque.  A good
> > way to do this might be to make all of the fields of the T[new] public but
> > undocumented.  If you *really* want to mess with it, you'll read the source code
> > and figure it out.
> Check while delete still exists. Please use malloc for that stuff.

As long as I can get at the pointer to the memory block held by T[new] I can pass
it to GC.free.  All that would really be needed is a .ptr property that does
something like what .ptr does for T[]s.

> So now: every place I've said "check" means there was implementation and
> book-quality illustrated documentation that Walter and I have done with
> the sweat of our brow. At the end we looked at the result and concluded
> we should throw away all that work.
> Andrei

This begs the question:  Why?  Walter's post on the subject was rather brief and I
can't understand for the life of me why you guys would throw away such an elegant
solution.  Given that we already agree that a T[new] can be implicitly cast to a
T[], the lack of closure under ~, .dup, etc. seems like a non-issue.  When I was a
beginner, before I got into templates, a major attraction to D was that it was a
fast, compiled language where basic things like arrays (mostly) just worked.  To
take away all the syntactic sugar for appending and lengthening from arrays and
push this into a separate library type that doesn't feel like a first class object
or (I assume) even support most array semantics would be a massive, massive kludge
no matter how well-implemented that library type was.




More information about the Digitalmars-d mailing list