Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lifetimes Intro slides #64

Merged
merged 1 commit into from
Jun 13, 2023
Merged

Lifetimes Intro slides #64

merged 1 commit into from
Jun 13, 2023

Conversation

listochkin
Copy link
Member

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 like Vec, String, or Box 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 and T: '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.

@jonathanpallant
Copy link
Member

First pass looks good but I'm going to check again on my laptop instead of my phone.

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 like `Vec`, `String`, or `Box` 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` and `T: '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.
@jonathanpallant
Copy link
Member

I proposed some minor changes in #65, which will merge into this branch.

@jonathanpallant jonathanpallant merged commit 41ced1f into main Jun 13, 2023
@jonathanpallant jonathanpallant mentioned this pull request Jun 13, 2023
@jonathanpallant jonathanpallant deleted the lifetimes-intro branch July 26, 2023 10:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants