The demise of T[new]

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sun Oct 18 17:19:18 PDT 2009


dsimcha wrote:
> Here's my proposal for how T[new] should work:
> 
> 1.  It should be a reference type to be consistent with slices.  Yes, slices are
> kind of a hybrid, but they're more semantically similar to reference types than
> value types.  If you can't modify the length of a slice anymore, then for all
> practical purposes it will be a reference type.

Check.

> 2.  A T[new] should support all the same operations as a T[] with semantics as
> similar as common sense will allow, including indexing, ~, .dup, .idup, slice
> assign, etc.  Basically, it should have, to the greatest degree possible without
> defeating the purpose, the same compile time interface.

Check.

> 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.

> 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)

> 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.

> 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.

> 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.

> 8.  The first call to opSlice on a T[new] should set a flag that indicates that
> there may be multiple pointers to the underlying memory block.  Before that flag
> is set, appends to a T[new] should result in calls to GC.free() to free the old
> block whenever it needs to be expanded (since we can guarantee that we own it
> exclusively).  This will help deal with false pointer issues, since D's GC looks
> like it will remain conservative for the foreseeable future.

Uncheck.

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



More information about the Digitalmars-d mailing list