On Sunday, 2 February 2014 at 04:26:16 UTC, Adam D. Ruppe wrote:
On Sunday, 2 February 2014 at 03:38:03 UTC, Andrei Alexandrescu
wrote:
Whoa, this won't work without an explosion in language
complexity.
The complexity is already there, it is just hidden. But most
the capacity to deal with it is already there too:
Owning!T is just a struct with ~this() { free(me); }.
Referencing counting is just a struct with this(this) {
payload.ref++; } ~this() { payload.ref--; } (with a few
optimizations to remove ref++; ref--;, which IMO should be
there anyway!)
Borrowed is a reference we can use or copy, but must not free
(delete is deprecated!) and ought not store.
GC is a reference that we don't have to free AND is ok to store.
The language just conflates the latter two. And the spec even
gives us some hope that it isn't supposed to with the scope
storage class, though IMO the difference is more of a type
thing than a storage class thing. A GC reference should
implicitly convert to a borrowed reference (e.g. alias slice
this;) but not vice versa. The only way to go from borrowed ->
GC (or any other really) would be cowboy it with cast() or
copying the contents.
BTW I like a lot of the ideas Rust has in this regard, but I
don't think we have to go all the way they did. But having:
char[] foo = new char[](1024);
and
char[1024] buffer;
char[] foo = buffer[];
both work and yield exactly the same type is trouble.
I see light ...
There is one little complication of owning pointers interacting
with borrowed pointers that might prevent a straightforward
approach (I'm sure there's more): owning pointers must not go out
of scope or be reassigned as long as there are outstanding
references to them alive (i.e. in scope as well).
I don't see ATM how this could be done at zero cost without
intrinsic compiler support. Only the compiler could enforce this
free of cost as far as I see.