[Dlang-study] [lifetime] Let's focus on escape analysis

György Andrasek jurily at gmail.com
Tue Jan 19 13:44:05 PST 2016


On Monday, 2 November 2015 at 16:03:04 UTC, Andrei Alexandrescu 
wrote:
> I don't follow Rust much, but my perception from following the 
> trade news is that since launched it has scored a few victories 
> (an OS project, a safe Doom implementation) but by and large 
> the excitement has subsided after the pre-release excitement 
> gave way to the post-1.0 certainty. The status seems to be - 
> things aren't as great as they were cracked to be. Putting 
> ownership front and center just makes things difficult, often 
> for no good outcome.

The Rust devs have made a bunch of braindead design decisions 
that turned it from a promising systems language into a RAII 
tutorial for Rubyists. Finalizing those in 1.0 is what drove 
people away, including me.

That said, lifetime management is the one thing they did exactly 
right.

The key thing to observe here is that we already have lifetime 
semantics everywhere, it's just not always checked by the 
compiler. GC languages get around the issue by extending the 
unchecked lifetimes to infinity, the problem we have now is that 
this is incorrect without the GC. We don't need to add extra 
complexity or runtime overhead to do it right, just keep more 
information in the compiler and some syntax to talk about it.

In Rust, all object and reference lifetimes are tracked by the 
compiler, at no runtime cost. You can say "I'm only allocating 
objects that don't outlive me", and have it checked transitively 
for all references into those objects. You can say "my lifetime 
will be the shortest of the constructor arguments" or "my 
lifetime is independent of them".

Safe RC is almost trivial in Rust, they have both a thread-local 
`Rc<T>` and an atomic `Arc<T>` in the standard library. It's also 
very easy to write, say, lifetime-safe glib bindings, where the 
refcount semantics are documented externally.

It's almost always inferred away, there's no syntax overhead for 
the common case. Most people don't need to care beyond what 
they're already familiar with from the curly braces. In fact, 
neither `Rc<T>` nor `Arc<T>` have a single explicit lifetime 
annotation in their public API. It Just Works(tm), wrong usage 
will simply not compile.

For D, I believe this could be implemented without breaking any 
existing correct code, maybe with syntax like

     C!A foo(A: scope)(C!A c) { return c; }

or

     scope!A C foo(scope(A) C c) { return c; }

which with lifetime inference could safely be written as

    C foo(C c) { return c; }

Of course it gets tricky with mutability, raw pointers, 
non-static lifetimes etc, but Rust has been exploring the 
solution space for years now. It would be a shame to just ignore 
them, especially when people are already starting to do the same 
for C++: https://www.youtube.com/watch?v=hEx5DNLWGgA



More information about the Dlang-study mailing list