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