+1 on making Phobos GC-free.

On Sunday, 2 February 2014 at 07:35:21 UTC, Andrei Alexandrescu wrote:
On 2/1/14, 10:00 PM, Frank Bauer wrote:
On Sunday, 2 February 2014 at 05:41:53 UTC, Andrei Alexandrescu wrote:
Sure. While you're young typecheck this:

class A {
  auto stuff() { ...; return this; }
}


Andrei

It would be a Borrowed!A, I would say, no matter how an A is allocated. A GC!A, an ARC!A and an Owning!A convert equally well to a Borrowed!A. As long as the Borrowed!A is in use (i.e. scope) after stuff() returns, the A object must not be freed (compiler enforced). Would that make sense?

No.

What I'm driving at is that right now the type is A, as is in a variety of other situations. It would be a whole different language that would be wholly incompatible with D.


Andrei

Why is that? I propose the new memory regime to be 100% compatible with all existing D code. It is way more powerful than anything scope can do. And it seems a lot less work to me than going through GC optimization and custom allocator tracing hell.

Let's see how far we can get if we require none of the existing D code to break.

Example: this is current D code that runs unchanged and with the same semantics under the new memory regime. GC(T) and Borrowed(T) remain under the hood:

class A {
    A foo() { return this; }   // returns Borrowed!A
}

void main () {
    A m1 = new A;   // m1 is a GC!A
    A m2 = m1;      // m2 is a Borrowed!A
    A m3;           // Borrowed!A
    m3 = m1;        // fine: assignment from GC!A to Borrowed!A
m3 = bar(m1); // fine: m1 converted from GC!A to Borrowed!A, assignment from Borrowed!A to Borrowed!A m3 = bar(m2); // fine: m2 already Borrowed!A, assignment from Borrowed!A to Borrowed!A m1 = new A; // fine: can reasssign GC!A although there are outstanding references
    m1 = m2;        // fine: can reassign GC!A to a Borrowed!A
}

A bar(A a) {        // takes and returns Borrowed!A
    A b1 = a;
    return b1;
}

Now here it comes: if, on the other hand, I replace the first 'new' with, say e.g., 'newOwning' (or '~', whatever), I get GC-free code:

A m1 = newOwning A; // m1 is an Owning!A, allocating on the heap and freeing when it goes out of scope

Then these lines above would be in error:

m1 = new A; // error: can't reassign to m1 because m2 and m3 still referencing m1 (same for newOwning)
    m1 = m2;        // error: can't assign Borrowed!A to Owning!A

ARC(T) could be implemented similarly.

Nothing changes one bit for those who want to use the GC as before. ARC(T) and Owning(T) would be *ADDED* on top of the existing language spec.

Emplacement new, as Adam mentioned, is not a problem: you always get to the emplaced object with a Borrowed!T. The underlying memory is managed separately and automatically as a GC!M, ARC!M or Owning!M (M could be an array of bytes, e.g.).

Reply via email to