Hacker News new | past | comments | ask | show | jobs | submit login
The Power of Lifetimes (jondgoodwin.com)
107 points by Ygg2 on April 19, 2019 | hide | past | favorite | 7 comments



> The use of a special kind of lifetime annotation, where the lifetime has to match exactly, can be used to get around this limitation.

This is already expressible in Rust, using invariant lifetimes. You can hand someone an opaque invariant lifetime, let them build a mutable cyclic data structure with it, and then pass that data structure around.

This use of invariant lifetimes, called "generativity," is described in more detail here (https://raw.githubusercontent.com/Gankro/thesis/master/thesi...) in section 6.3, which describes a way to use lifetimes as unique tokens for all sorts of use cases.

And even more closely aligned with what the article is talking about, Catherine West has put together a library that uses generativity to provide a safe interface to a garbage collected heap, as part of a reimplementation of Lua: the `gc-arena` crate in https://github.com/kyren/luster


Generativity is truly the most mysterious part of Rust type system. Like template metaprogramming in C++, I see the great (ab)use potential in the future.


The D programming language now supports tracking of lexical lifetimes. For a simple example,

    int* foo() {
        int i;
        int* p = &i;
        int* q = p;
        return q;
    }
is detected as an error. This tracking is even done across function calls:

    int* bar(scope int *p); // p doesn't escape bar()
    int* abc(return scope int* p); // p doesn't
       // escape abc() but is returned from it

    int* foo() {
        int i;
        return bar(&i); // ok
        return abc(&i); // error
    }
The annotations can be explicit, or can be inferred by the compiler by analyzing the function bodies.


That's cool, though it doesn't seem to work through a level of indirection. https://d.godbolt.org/z/zkm39N

(I don't know much about dlang. I got the compiler flags from googling and happening upon the test case in this PR https://github.com/dlang/dmd/pull/8504/files#diff-bb6a3ed8a5... )


The code has to be annotated with `@safe:` and use the `-dip1000` compiler flag, which enables the checking. With such:

    test.d(9): Error: reference to local variable s assigned to non-scope s.i


Thanks. Indeed it needs the attribute like `@safe: S* foo() {` (and `-dip1000` seems to be unnecessary with it).


To correct my comment: `-dip1000` is still needed because `@safe` is overly restrictive. `@safe` prevents taking the address of `s` entirely regardless of how it's used, so `-dip1000` is needed to allow it when it's safe (such as using `&s` without letting it escape scope).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: