Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
These are based on how I've been teaching lifetimes in the past 8-12 months. I build up an intuition around functions returning references and using annotations to tag returned references and their corresponding sources of data. When I do it live I tend to have more intermediate situations covered: functions that only accepts references but don't return references, a function that takes a single reference and returns many, their variations with non-reference parameters and returned components, you get the idea. I dropped most of it because they don't work as well in slide format.
Also, while this flow leads to a much gentler introduction in general, it requires covering static data and
'static
lifetime before anything else, and there's this awkward chicken-and-egg phase early. In my experience, it can be tip-toed over pretty easily. I actually started introducing the concepts of three memory types: static, stack, and heap very early, - on day 1 or 2. C/C++ people don't need it per se, but even they benefit from discussing it when we talk about containers likeVec
,String
, orBox
and recursive structs or enums. This way by the time we talk lifetimes the audience has a benefit of familiarity ("Oh,static
, I remember: that's for static memory!")One example I add in the middle actually shows how adding lifetime annotations helps the programmer find and fix bugs in code. Some of the code fragments are subtly incorrect, and I'd love to add speaker notes for them so that trainers won't stumble through them too much. I show this example to demonstrate that these annotations are not only to keep the compiler happy, but also for your benefit as well. Another attempt at turning lifetimes perception around: they are friends, not enemies.
Despite the fact that there's quite a bit more content I actually cover less in terms of material. I don't mention elision, non-lexical lifetimes, lifetime dependencies and sub-lifetimes. In my view these concepts are too advanced to present to intro groups, and advanced groups would benefit from doing more exploratory lifetime coverage via Serde exercise and / or
std::thread::scope
API. It has everything: sub-lifetimes, higher-ranked trait bounds for lifetimes, and all of that mixed with multithreading safety discussion! Still, if we want to keep old contend I don't mind moving my material into a separate deck.I do, however, mention a few type system aspects of lifetimes, mostly around
T: 'a
andT: 'static
. Both show up in signature of standard library methods, both look very confusing for newcomers. For my training flow (syntax -> traits -> memory -> multithreading
) this information bits play out really well.std::thread::spawn
has a+ 'static
in its signature twice, and I can point to it and tell my audience: "remember this? we talked about it yesterday!"Finally, I'm afraid my terminology around lifetime annotations, lifetime type parameters, and lifetime generics is not entirely accurate. I try to find a balance around being precise and not overload the audience too much.