Inband lifetimes blog

@Mark_Simulacrum has a nice blog post exploring how inband lifetimes (Rust 2018 edition feature) look from the perspective of a specific rustc crate. I've not played with them myself just yet, but my initial reaction is they don't bring enough benefit to the table and potentially create more confusion and/or leave room to make code harder to read/follow, as Mark's examples show.

I've always liked that Rust is very explicit in its type signatures, for the most part (lifetime elision being the opposite of that, but I've found that to be mostly striking the right balance). I'm slightly worried that the language is being morphed in directions that add extra optionality to how things are written, hide a bit more things, and in general, seem to be optimized for writing code (as opposed to reading). I'll reserve stronger judgment until I actually play with this myself, however.

Curious what others think.

8 Likes

One of the most common questions about lifetimes is about this line of code:

impl<'a> Foo for &'a i32 {

Why do I need the 'a twice? It feels like boilerplate.

Even when explained, most people still react with a "okay I guess I can live with that but I don't like it." What they tend to write,

impl Foo for &'a i32 {

will now just work.

I think this is another instance of There’s more to mathematics than rigour and proofs | What's new; this is a feature that's great for the pre and post rigorous stages, but makes people in the "rigorous" stage uneasy.

2 Likes

I think you have a typo in your second snippet, since it is identical to your first one.

I'd be fine with more elision, like @anon15139276 suggested, so you can write:

impl Foo for &'_ i32

although I don't mind the "boilerplate" of status quo all that much. The existing formulation is also consistent with generic types:

impl<T> Foo for T

once you take into account that &'a i32 is a type and not a "modified" i32.

Inband lifetimes, however, appear to go a lot further in what they allow. Couldn't we move a bit more incrementally and conservatively, get some experience with slightly more elision, and then reassess? Why do we need a "big bang" type of migration?

3 Likes

ugh, thanks

People don't like it equally as much, maybe even more, since generic types are used more often than lifetimes :slight_smile:

2 Likes

All I can say is there will be groups of people who don't like any particular aspect of Rust :slight_smile:. It doesn't mean things need to change - the language needs to stay true to its principles, IMO, rather than being pulled in various directions. And for those changes that are deemed a possible improvement, try to do them incrementally, see how they play out with the wider userbase/collective experience, and then see if we need to go further.

5 Likes

These forms were already accepted as part of RFC 141, and they are implemented today in the 2018 Edition preview: Rust Playground

3 Likes

FWIW, even now that I know what I'm supposed to be doing, that's still not what my fingers tend to type. What I seem to always type the first time is just impl Foo for &i32, and then my brain kicks back in and I go add the lifetime.

So I'm way more excited by elision improvements, since just getting rid of the <'a> doesn't feel like it's solving my actual wish, here.

And not needing a named lifetime seems pretty common, like the first for & impl that comes to mind:

Is there a nightly-2015 feature gate that can be used to enable just them? Or is it mixed up in in_band_lifetimes?

2 Likes

It's part of in_band_lifetimes (plus underscore_lifetimes for the underscore version).

1 Like