DIP1000: Scoped Pointers (Discussion)
deadalnix via Digitalmars-d
digitalmars-d at puremagic.com
Sat Aug 13 09:16:57 PDT 2016
On Saturday, 13 August 2016 at 14:35:09 UTC, Andrei Alexandrescu
wrote:
>> You have the detail in your inbox for close to 2 years now.
>
> Thanks. Do you have a date or title of the thread? -- Andrei
In the very thread that ended up with DIP1000 .
I suggested various changes int he DIP, which I'm copying bellow.
You can read it in context digging around the 26/11/2014 .
Copying the proposed changes to DIP 1000:
=========================================
Ok, resurrecting the thread, I'd like to propose another way to
specify this. The end result should be very close but should
provide a simpler/clearer mental model.
Every expression has now has a lifetime associated with it, and
can be marked as "scope". It is only possible to assign b to a if
b has a lifetime equal or greater than a's.
An infinite lifetime is a lifetime greater or equal than any
other lifetime. Expression of infinite lifetime are:
- literals
- GC heap allocated objects
- statics and enums.
- rvalues of type that do not contain indirections.
- non scope rvalues.
Dereference share the lifetime of the dereferenced expression (ie
infinite lifetime unless the expression is scope). Address of
expression shared the lifetime of the base expression, and in
addition gain the scope flag.
Comment: Using these rule, we basically define any indirection
being of infinite lifetime by default, and we propagate the
lifetime when scope. The addition of the scope flag for address
of is necessary to disallow taking address->dereference to yield
an infinite lifetime.
Variables delcarations (including parameters) have the lifetime
of the block they are declared in (2 pitfalls here, I don't have
good solution, and the original spec do not as well : #1
destructor, finally, scope statement and #2 closures). Use of
these variables shared the lifetime of the variable, unless they
qualify for infinite lifetime. Parameter's lifetime are
unordered, meaning smaller than infinite, greater than the
function's scope, but not equal to each other nor greater/smaller
than each others.
Working from there, I'd like to define properly the pitfalls #1
and #2 . These are the great absent from what is discussed so far.
const scope works for Rust, but isn't gonna fly for D. That is a
good idea, but not worth the cost.
I'd like to discuss the pro and cons of such a definition
(compared to rust for instance):
- We can't specify explicit lifetime for parameters. I'm not
sure how limiting it is. This is something we can extend toward
anyway in the future, so I suggest we put that asside for now.
- We can't define lifetime of indirections explicitly. This
clearly limit the expressiveness compared to Rust, but I it allow
for scope to be a storage class rather than a type qualifier, and
I think this is a winner when looking at the complexity /
expressiveness ratio.
- In D, mutability and burrowing are decoupled, which i think is
a plus compared to Rust. That prevent us to go for things like
the proposed const scope, but simply the concept of both
mutabilities and burrowing in D, while allowing some pattern that
aren't easy to get in Rust (multiple writable reference to one
object in a single thread for instance, is trivial in D).
Maybe I'm convincing myself, but I think we have a winner here.
Andrei, what do you have in mind when you say scope should be the
default ? I do think this is a sensible default, but I fail to
see how this is gonna translate with existing code in a nice
manner.
More information about the Digitalmars-d
mailing list