The recent discussion about the word 'lifetime' in rust interests me, because it is something I found confusing at first... but I still don't see any of the alternatives ('scope', 'lifespan', 'borrow bound') as being any meaningful improvement.
I think the lifetime guides should be more explicit about how memory management occurs.
Something like this:
When the instance X of type T is freed in rust and its destructor (if any)
is invoked, we refer to this as 'dropping' X.
X will be dropped if:
- It goes out of a scope
- It's immediate parent is dropped
*T in rust is a 'raw' pointer, like a C pointer.
*T can result in a segmentation fault like in C, if the memory it points
to has already been dropped (Use after free).
&T is a special type in rust that prevents use after free errors by
applying compile time guards enforcing safe usage.
Typically the compile time guards are automatically determined using
static analysis, but sometimes ambiguities require explicit hints when
writing an API. In these cases it is necessary to hint to static type
checker what the the appropriate lifetime for a &T is.
The existing lifetime definition:
A lifetime is a static approximation of the span of
execution during which the pointer is valid
Doesn't really cut it for me.
It needs to be explicit 1) that lifetimes are for the static type checker, and 2) that they are
more than just for borrowed pointers.
For example, for a trait or closure, the lifetime is not the duration during which the pointer is valid. It's a lower bound on the possible lifetimes of other types that can go into either that closure or trait.
For example, to pass a closure to a thread it must be 'static, which means that the lower bound for any lifetime used in the closure is static. This for example:
let foo = 0u;
let bar = |:| { let y = foo + 1; ... }
The closure in this example has a lifetime which is <= the lifetime of foo, which it uses. This is < 'static, so bar cannot be 'static.
The same is true of structures and traits. A boxed trait Box<Foo + 'a> means the struct implementing Foo contained in the box must have an lifetime of at least 'a.
It's almost like we have two completely separate ideas:
1) Lifetime <--- The lifetime of a borrowed pointer
2) Lifetime bound <---- The lifetime on a closure, struct, trait, etc.
OP Here. Yes, now I agree with you that doing a “Replace All” on lifetime with another term does not really solve the problem. (I have replied you on the RFC discussion.) We need to distinguish some existing lifetime-related terms (concepts) clearly, including the two you just mentioned.
The issue is &'a is so common in Rust code. We simply call it lifetime 'a, which is misleading. It is not any object’s or pointer’s lifetime, but a set of lifetime requirements (or lifetime bound in your term) that every borrower imposes on the borrowed resources. It is the B I mentioned in the last section of my blog post:
When we talk about borrow, there are three different kinds of “lifetime” involved:
A: the lifetime of the resource owner (or the owned/borrowed resource)
B: the “lifetime” of the whole borrow, i.e. from the first borrow to the last return
C: the lifetime of an individual borrower or borrowed pointer
The required condition is A >= B, where B = C1 U C2 U ... U Cn.
I think scope is a great word, because my own important insight was that "lifetimes" represent the scope a borrowed reference lives in -- it's not really about the life of the value you borrow from.
Yes if you have a lifetime 'a, it will correspond to some reference on the stack in a scope somewhere up the callchain.
I think the lifetime guides should be more explicit about how memory management occurs.
Something like this:
The existing lifetime definition: Doesn't really cut it for me.It needs to be explicit 1) that lifetimes are for the static type checker, and 2) that they are more than just for borrowed pointers.
For example, for a trait or closure, the lifetime is not the duration during which the pointer is valid. It's a lower bound on the possible lifetimes of other types that can go into either that closure or trait.
For example, to pass a closure to a thread it must be 'static, which means that the lower bound for any lifetime used in the closure is static. This for example:
The closure in this example has a lifetime which is <= the lifetime of foo, which it uses. This is < 'static, so bar cannot be 'static.The same is true of structures and traits. A boxed trait Box<Foo + 'a> means the struct implementing Foo contained in the box must have an lifetime of at least 'a.
It's almost like we have two completely separate ideas:
1) Lifetime <--- The lifetime of a borrowed pointer
2) Lifetime bound <---- The lifetime on a closure, struct, trait, etc.