Rust's second most complicated feature explained

แชร์
ฝัง
  • เผยแพร่เมื่อ 20 พ.ย. 2024

ความคิดเห็น • 128

  • @letsgetrusty
    @letsgetrusty  3 หลายเดือนก่อน +3

    Get your *FREE 4-Day Rust training* :
    letsgetrusty.com/bootcamp

  • @tirushone6446
    @tirushone6446 3 หลายเดือนก่อน +74

    I like how even after learning rust for over a year lifetimes still scare me deep down, because of stuff like this.

    • @11WicToR11
      @11WicToR11 3 หลายเดือนก่อน +4

      thats the thing i dont like about rust, i mean after years of writing typescript i dont think i would ever find a piece of code in some lib i couldnt just look at and understand, but in rust i feel like i m absolutely not gonna get some of these never ever xD but i can write my snake app in rust and call it an achievement and that gives it a point back :D

    • @tyrellnelson
      @tyrellnelson 3 หลายเดือนก่อน

      Lifetimes? Whats that, is that what happens when you call .clone()?

    • @lobotomy-victim
      @lobotomy-victim 3 หลายเดือนก่อน +5

      ⁠@@11WicToR11yeah typescript doesn’t require a lot of understanding of anything

    • @11WicToR11
      @11WicToR11 3 หลายเดือนก่อน

      @@lobotomy-victim thats just a perspective statement, good for you that you left us in the dust

    • @letsgetrusty
      @letsgetrusty  3 หลายเดือนก่อน +2

      Nothing to be scared of! Most of the time you don't even have to worry about lifetimes :)

  • @viniciusataidedealbuquerqu2837
    @viniciusataidedealbuquerqu2837 3 หลายเดือนก่อน +17

    2:06 holy cow this graph is so descriptive and the relation between them at the same time is godlevel pedagogy. tysm

    • @letsgetrusty
      @letsgetrusty  3 หลายเดือนก่อน +1

      I got you :)

  • @catasterphe
    @catasterphe 3 หลายเดือนก่อน +132

    too complicated for me but thanks
    edit: i think i get it now 🔥

    • @letsgetrusty
      @letsgetrusty  3 หลายเดือนก่อน +10

      Awesome to hear :)

    • @cosmiclattemusic
      @cosmiclattemusic 3 หลายเดือนก่อน +3

      imagine me, a fresh newbie that just started learning Rust jumping into this video. I'm half devastated of how complex this is but excited at the same time, it's gonna be actually fun to learn this well in some future.

    • @everythingbuttherain6323
      @everythingbuttherain6323 3 หลายเดือนก่อน +2

      @@cosmiclattemusic pretty sure even if u gonna work with them and use well u still would return back to lifetime docs & explanation videos like i do sometimes)) so don't worry

    • @cosmiclattemusic
      @cosmiclattemusic 3 หลายเดือนก่อน

      @@everythingbuttherain6323 thanks for the really accurate advice ✨

    • @LtdJorge
      @LtdJorge 3 หลายเดือนก่อน

      @@everythingbuttherain6323 also you don’t need to learn this at the beginning. Just start with the things that apply to every language, understanding the standard library, then go on to more complex traits and lifetimes topics. And finally learn every low level detail, like this or atomics, where I find reading the source of hugely popular crates together with the std doc and the book side by side is the best way.

  • @undefined24
    @undefined24 3 หลายเดือนก่อน +5

    **Summary**
    - Rust drops in revers order
    - The first implementation, the formatter function's lifetime annotation is telling the compiler that any reference passed into this should live as long as the formatter method live
    - Due to the reverse order drops, the str variable dropped before the formatter
    - Redefined the lifetime annotation by using for

  • @ARS-fi5dp
    @ARS-fi5dp 3 หลายเดือนก่อน +16

    Thanks to you, i learned memory management, ownership, and borrowing, passing a large portion of the rust learning curve and getting a deeper understanding of low level programming 😀

    • @letsgetrusty
      @letsgetrusty  3 หลายเดือนก่อน +6

      Glad to help! Comments like this keep me going :)

  • @polanas1879
    @polanas1879 3 หลายเดือนก่อน

    I've never really grasped HRTBs despise reading several explanations, but this video finally made it click. Great work!

  • @HaydonRyan
    @HaydonRyan 3 หลายเดือนก่อน +2

    Amazingly well done! I found the first half to be a great pace, the second half was a little fast - need to take a breath when ending a complex statement - and a second or 3 more for the code to be on screen. Very advanced topic which is very helpful to have straight forward examples of :)

  • @AndrewBrownK
    @AndrewBrownK 3 หลายเดือนก่อน +45

    I FRICKING LOVE TYPE LEVEL PROGRAMMING I CAN’T GIVE ENOUGH TYPE LEVEL PROGRAMMING

    • @hermestrismegistus9142
      @hermestrismegistus9142 3 หลายเดือนก่อน +1

      You would love Idris. Its types are so powerful that one can prove math theorems at the type level.

    • @enticey
      @enticey 3 หลายเดือนก่อน

      @@hermestrismegistus9142 wait you guys are owning your data?

    • @everythingbuttherain6323
      @everythingbuttherain6323 3 หลายเดือนก่อน +1

      caught another typemasturbator here)

    • @plaintext7288
      @plaintext7288 3 หลายเดือนก่อน

      Try C, having to memorize all the type shenanigans doubles the fun :)

  • @dealloc
    @dealloc 3 หลายเดือนก่อน +8

    Now that you are on a roll about generics and traits, it would be awesome to have a video on "magic handler functions", where a handler trait is implemented for closures based on the arguments that conform to a common trait. This then allows the user to define a function whose arguments uses types to "extract" data from a context.
    Notable examples of this pattern is seen in Axum's extractors and Bevy query and systems. Albeit there are some downsides to the pattern, it can form a nice API without having to do all the plumbing yourself.

    • @Holobrine
      @Holobrine 3 หลายเดือนก่อน

      Yes please I must understand this wizardry

    • @poszu
      @poszu 3 หลายเดือนก่อน

      AFAIR, Jon explained this in decrusting Axum: th-cam.com/video/Wnb_n5YktO8/w-d-xo.html

    • @polanas1879
      @polanas1879 3 หลายเดือนก่อน

      For anyone looking for a decent explanation, there's a mini book called "Dependency Infection Like Bevy From Scratch" which covers the basics of the pattern

  • @_rushii
    @_rushii 3 หลายเดือนก่อน +1

    I never quite wrapped my head around this until now, thanks very much!!

  • @nmay231
    @nmay231 3 หลายเดือนก่อน +1

    Thank you so much for making a video about this! It's hard to get into and understand high-level concepts like this without a great introduction as you presented it.
    I have to admit, I'll still need time to wrap my head around all of the implications, but here's a tip for other's who are also struggling. Remember when you have a trait with some methods, you can attach the generic to the trait/trait implementation itself `trait MyTrait { ... }` or you can attach the generic to only the method of the trait `trait MyTrait {pub fn method() { ... } }`. So the first example, where the generic (and its trait bounds) are defined on the struct/enum, means that the generic is unchanging for a particular instance of that struct or enum. In the second example, the generic and trait bounds are unchanging/static for a particular call to a method; this includes the values passed to the method and returned from it.
    I think higher-ranked trait bounds are the next "russian doll" in this example. So higher ranked traits do not restrict the inputs and output of a method, but instead restricts aspects of the output with respect to itself. An example would be a closure returned from a method, where the closure's arguments are constrained somehow, but not constrained at the time when the method call was made. I write this without a full understanding, so I think the only real takeaway is the russian-doll analogue, if that even helps any, lol.

  • @Mempler
    @Mempler 3 หลายเดือนก่อน +3

    So, tl;dr. In this case, the "for" does exactly the same as

  • @redcoreit
    @redcoreit 3 หลายเดือนก่อน +1

    Ok, this was 10/10! Excellent complexity/time/depth ratio!

    • @letsgetrusty
      @letsgetrusty  3 หลายเดือนก่อน +1

      Thank you! :)

  • @returncode0000
    @returncode0000 3 หลายเดือนก่อน

    This is the video I was waiting for 🔥 I always search for explanations on the more complicated stuff in rust but a.) there are not many and b.) most of them doesn't explain it very well or deep enough. I'm also looking for videos who explain functional programming approaches in rust more deeply but there is also not much out there in a digestable format. Anyway, thank you for this video, I'm very thankful you put so much effort into explaining complex stuff!

  • @jonnyso1
    @jonnyso1 3 หลายเดือนก่อน

    DUDE ! Thank you ! I was reading some source some time ago and just couldn't find out wtf that was !

  • @iyxan23
    @iyxan23 3 หลายเดือนก่อน +8

    would be really cool if you would dive into those codebases like serde and break down how those types actually work lol

  • @clusterdriven
    @clusterdriven 3 หลายเดือนก่อน

    This channel is great! Thank you for bringing more of the advanced side of Rust.

  • @bene7042
    @bene7042 3 หลายเดือนก่อน

    I have been programming in Rust for years but have never used this but this is actually really nice and you explained it well!

  • @vondert173
    @vondert173 3 หลายเดือนก่อน

    Thank you so much! I am planning to start implement complicated closures in my crate. This video 100% saved me time in the future

  • @aabhishek4911
    @aabhishek4911 3 หลายเดือนก่อน +2

    So basically avoid creating code that makes you use this feature, got it.

  • @el_carbonara
    @el_carbonara 3 หลายเดือนก่อน

    thanks it starts to make more sense to me now. glad to see more complex rust as kinda stop learning anything new keeping to intro topics

  • @AreQ212
    @AreQ212 3 หลายเดือนก่อน

    I was definitely missing that part, really appreciate that video! :D

  • @denizsincar29
    @denizsincar29 2 หลายเดือนก่อน

    Oh i think i got it earlyer. The thing is that a generic type can be restricted by a trait like:
    fn add(left: T, right: T) -> T {
    a+b
    }
    I didn't test if this compiles. But than i realized that an output type can be different.

  • @EngineerNick
    @EngineerNick 3 หลายเดือนก่อน +1

    Thats very cool thankyou :) Whenever I am writing rust i have this feeling that i should be able to convice the borrow checker of a thing, but I only succeeed about half the times that I should. Hopefully this helps next time I get stuck :)

  • @kolserdav
    @kolserdav 3 หลายเดือนก่อน

    Wow, it's so beautiful and clear code examples 🎉 Good job, Bogdan, thank you 🙏

  • @ClearerThanMud
    @ClearerThanMud 3 หลายเดือนก่อน

    I've always wanted to understand that better; thanks! BTW, what tool did you use to create this video? Manim? MotionCanvas?

  • @Starwort
    @Starwort 3 หลายเดือนก่อน +1

    5:10 the lifetime is *not* linked to that of the `impl Fn()` (that would be `impl Fn() + 'a`) - instead, it is inferred at its first call site to be 'static, which is longer than the second reference is valid for

    • @algorythmis4805
      @algorythmis4805 3 หลายเดือนก่อน

      Why is it inferred to be 'static?

    • @Starwort
      @Starwort 3 หลายเดือนก่อน +1

      @@algorythmis4805 that's how it's first used. Arguably it's an inference bug, but honestly it's a contrived example

  • @theLowestPointInMyLife
    @theLowestPointInMyLife 3 หลายเดือนก่อน

    one of my grievances with rust is the multiple ways you can do things, the example with trait bounds sums it up, you have this relatively complex thing for beginners, and you have 3 different ways of doing it, in the template, with where or with impl
    it adds much more overhead to reading and understanding code for beginners, one way should be decided on and move on

  • @felixtoulgoat3185
    @felixtoulgoat3185 3 หลายเดือนก่อน

    That's pure insanity... I love it. I should really get started with rust.

  • @jaans3712
    @jaans3712 3 หลายเดือนก่อน +3

    I had one too many whiskeys for this video. I try again tomorrow

  • @vittoriuz
    @vittoriuz 3 หลายเดือนก่อน

    Thank you for releasing a video on this topic!

    • @letsgetrusty
      @letsgetrusty  3 หลายเดือนก่อน

      My pleasure :)

  • @kuqmua755
    @kuqmua755 3 หลายเดือนก่อน

    It will be nice if compiler generates error explanation video like yours

  • @valcubeto
    @valcubeto 3 หลายเดือนก่อน +1

    Gotta see this video again...

  • @porky1118
    @porky1118 3 หลายเดือนก่อน

    I think I used this feature once. And before I used it, I wanted to use it, because I thought I had seen it and hoped it would be helpful, but then it seemed like it didn't exist and I thought I just misremembered.

  • @TheRocreex
    @TheRocreex 3 หลายเดือนก่อน +6

    2:27 I think what you meant to say was the other way round: The input reference must be valid at least as long as the returned reference?

    • @doesdev
      @doesdev 3 หลายเดือนก่อน

      The function contract says the returned reference must live at least as long as the input reference; hence the returned reference may only be used while the input reference is valid

  • @MasterHigure
    @MasterHigure 3 หลายเดือนก่อน

    2:20 I prefer to think of it as
    fn first_word(s: &'a str) -> &'b str where 'a: 'b {...}
    We are specifically _not_ requiring that the input variable and the output have the _same_ lifetime. So clarifying that they are different is much clearer and more transparent than writing it as though they are the same and letting the compiler silently and invisibly subtype it properly for us.

    • @Starwort
      @Starwort 3 หลายเดือนก่อน

      Lifetimes are covariant, which means the two are equivalent. IIRC the reference explicitly states that fn(&T) -> &U is equivalent to fn(&'a T) -> &'a U

    • @Starwort
      @Starwort 3 หลายเดือนก่อน

      (yep - see Lifetime Elision in either the Book or the Nomicon)

    • @MasterHigure
      @MasterHigure 3 หลายเดือนก่อน

      @@Starwort I'm aware. I just think lifetimes are difficult enough as they are and we don't have to throw in covariance into the mix at the same time, especially when teaching it to newbies.

  • @scopulih8658
    @scopulih8658 3 หลายเดือนก่อน

    Very good explanation, thanks!

  • @emmanueltd7628
    @emmanueltd7628 3 หลายเดือนก่อน +13

    What is the most complicated feature then ?

    • @danny_hvc
      @danny_hvc 3 หลายเดือนก่อน +4

      My best guess is proc macros

    • @kadercarter
      @kadercarter 3 หลายเดือนก่อน

      I'd assume the borrow checker

    • @staywithmeforever
      @staywithmeforever 3 หลายเดือนก่อน +2

      ​@@kadercarter No way borrow checker is this much complicated

    • @ElektrykFlaaj
      @ElektrykFlaaj 3 หลายเดือนก่อน +4

      @@kadercarter borrow checker is simple really. It requires some mental shift when you come from another language, but once you get it, it will be really easy.
      But macros... oh boy

    • @taragnor
      @taragnor 3 หลายเดือนก่อน +1

      Macros seem the most complicated for me. Mostly because there's no real good tutorial that goes step by step as to what each part of the macro does and then showing what Rust code it expands to and why.

  • @AnassIRIZI
    @AnassIRIZI 3 หลายเดือนก่อน

    great video, simple and to the point

  • @GeekOverdose
    @GeekOverdose 3 หลายเดือนก่อน

    Idk, I feel like for something to qualify as "second hardest" it would need to be some kind of async ffi proc macro magic, or something

  • @siya.abc123
    @siya.abc123 3 หลายเดือนก่อน

    Rust is the hardest programming language for me because I can't get used to this syntax. I'll stay with Go for now. Maybe I'll learn Rust in future

  • @abduljabbarazam943
    @abduljabbarazam943 3 หลายเดือนก่อน

    I didn't know this feature existed, until I found it in Rust Nomicon after watching the video. What's the most complicated feature?

  • @ARS-fi5dp
    @ARS-fi5dp 3 หลายเดือนก่อน +1

    Thank you 🌷

  • @sundae6610
    @sundae6610 3 หลายเดือนก่อน

    I'll remember this video for when i need it later haha

  • @NuflynMagister
    @NuflynMagister 3 หลายเดือนก่อน

    Дякую, Богдане!

  • @G11713
    @G11713 3 หลายเดือนก่อน

    The association of the lifetime of the reference argument to the lifetime of the closure *seemed like* an unfortunate, unnecessary, and counter-intuitive language constraint. However, in the case where the closure collects the provided input such as in an internal stack (aka, FnMut) then such constraints would obviously make sense. With that insight, I suppose the possibility of dynamic mutability within an Fn or FnOnce closure's would require persistence of the provided reference. Nice. Thanks.

    • @Starwort
      @Starwort 3 หลายเดือนก่อน

      Except it isn't true. The example at 5:10 is actually just the result of inference.
      A FnMut with an internal stack would be `impl FnMut(&'a T) + 'a`, tying the function's lifespan to its inputs' lifespans

  • @mintx1720
    @mintx1720 3 หลายเดือนก่อน

    Wait what if we actually have like `for T: Read`

  • @kocsis1david
    @kocsis1david 3 หลายเดือนก่อน

    There are a lot of complicated features in Rust. I wouldn't say this is close to being the second one. Many things are more complicated than this.

  • @catsolstice
    @catsolstice 3 หลายเดือนก่อน

    Good content 👍

  • @johnw.8782
    @johnw.8782 3 หลายเดือนก่อน +1

    See new "Let's Get Rusty" video, click new "Let's Get Rusty" video.

  • @thingsiplay
    @thingsiplay 3 หลายเดือนก่อน

    I still use Vim/Nvim as my Rust IDE.

    • @letsgetrusty
      @letsgetrusty  3 หลายเดือนก่อน +1

      Don't flex so hard on us mere mortals

  • @samjingwen
    @samjingwen 3 หลายเดือนก่อน

    What's the most complicated feature?

    • @krakow10
      @krakow10 3 หลายเดือนก่อน

      That's the joke, to make you ask this question out of curiosity
      Gottem!

  • @nyvyme
    @nyvyme 3 หลายเดือนก่อน

    that's why I prefer C

    • @nyvyme
      @nyvyme 3 หลายเดือนก่อน

      @@RustIsWinning understandable
      have a nice day

  • @omiraclx
    @omiraclx 3 หลายเดือนก่อน +1

    Now, do subtyping and variance.

    • @letsgetrusty
      @letsgetrusty  3 หลายเดือนก่อน +1

      Someone found the hardest feature ;)

  • @sc5shout
    @sc5shout 3 หลายเดือนก่อน

    so it's like "requires" in c++

  • @Shwed1982
    @Shwed1982 3 หลายเดือนก่อน

    Ничего не понятно но очень интересно

  • @damickillah
    @damickillah 3 หลายเดือนก่อน

    Your paid portal isn't sending me a reset password link. My original password, which I never changed, doesn't work anymore. Can you please advise or assist me with my issue?

    • @damickillah
      @damickillah 3 หลายเดือนก่อน

      Let me say, "...which I don't recall changing..."

    • @letsgetrusty
      @letsgetrusty  3 หลายเดือนก่อน

      Hey! Which email did you use to purchase to bootcamp!

    • @damickillah
      @damickillah 3 หลายเดือนก่อน

      @@letsgetrusty I am good Bogdan. You came through in the clutch and I am commenting here to let everyone know that you a good dude!

  • @affanyunas7693
    @affanyunas7693 3 หลายเดือนก่อน

    I still don't understand why I have to use lifetime. Everything was fine before I learned about lifetime.

    • @LemurFromTheId
      @LemurFromTheId 3 หลายเดือนก่อน

      It's because Rust actually cares about safety and correctness. In most languages lifetime annotations only exist in comments: "This function must not be called after close() has been called for the handle" etc. In Rust, this is encoded in the function signature. Lifetimes are necessarily part of a function's public API: they set boundaries on what callers are able to do with the arguments and the returned value - and what the function itself is able to do internally without breaking the calling code.

    • @affanyunas7693
      @affanyunas7693 3 หลายเดือนก่อน

      @@LemurFromTheId sometimes the compiler message makes me a little less confident. but it makes me improve myself when writing programs other than rust. shadowing, clone, and error handling make me a little less confident when writing code other than rust language. because my code looks very bad and not confident. i don't know if it really needs to be taken care of, because most drivers are made using c language and they are fine

    • @NovemberIGSnow
      @NovemberIGSnow 3 หลายเดือนก่อน

      ​@@affanyunas7693 Less than 2 weeks ago, a memory safety bug in driver code brought down millions of computers around the world. I'd rather we switched to using languages that had better memory safety guarantees than C if we're going to execute them in kernel space.
      Systems programming with lifetimes is annoying. Systems programming without lifetimes is dangerous.

  • @jmstevers
    @jmstevers 3 หลายเดือนก่อน

    is the voice for this video ai generated? or at least ai noise removal?

  • @germanmalinovsky1719
    @germanmalinovsky1719 3 หลายเดือนก่อน

    Then which is the first most complicated feature? Unsafe Rust?

    • @toby9999
      @toby9999 หลายเดือนก่อน

      I'd hate to thiink.... this was already harder than anything I've encountered in C++ in 30 years.

  • @skejeton
    @skejeton 3 หลายเดือนก่อน

    can they focus on making the language readable instead

  • @googleaccount7806
    @googleaccount7806 หลายเดือนก่อน

    Higher-ranked trait bounds are too high for my high ass

  • @toby9999
    @toby9999 หลายเดือนก่อน

    I still don't understand traits. Sorry. Rust is just way too complex. WTF

  • @pyyrr
    @pyyrr 3 หลายเดือนก่อน

    eh. this problem doesn't exist in c++ which i am thankful for

    • @arson5304
      @arson5304 3 หลายเดือนก่อน +1

      crowdstrike

  • @globulonz
    @globulonz 3 หลายเดือนก่อน

    What are shtrings and conshtraints? 😂

  • @s1v7
    @s1v7 3 หลายเดือนก่อน +1

    sometimes it seems to me that rust exists only to demonstrate your intellectual superiority over normies

  • @fuzzylogicq
    @fuzzylogicq 3 หลายเดือนก่อน +1

    And y’all still think cpp is harder😂😂…. Saw the func at 0:08 and my brain crashed….well time to go learn zig or stick to just plain old C

  • @draco_2727
    @draco_2727 3 หลายเดือนก่อน

    Rule number one of Code Club: Never talk about K.I.S.S. -- At least that's what it seems nowadays.

  • @sdramare864
    @sdramare864 3 หลายเดือนก่อน +2

    unfortunately, in practice, lifetimes and trait bounds make rust code write-only. It's very bad language design here

  • @megawavez
    @megawavez 3 หลายเดือนก่อน

    Programming in Rust is a huge brain drain - even simple tasks can require serious mental gymnastics.

  • @Siger5019
    @Siger5019 3 หลายเดือนก่อน

    What a waste of developer time

  • @simensgreen5374
    @simensgreen5374 3 หลายเดือนก่อน

    Is voice in this video AI generated?

    • @weeb3277
      @weeb3277 3 หลายเดือนก่อน +5

      no