Rust on Rails

Поделиться
HTML-код
  • Опубликовано: 2 окт 2024
  • Today's video explains how Rust helps us write code that has no execution paths that crash at runtime.
    Thanks very much to today's sponsor www.ditto.live.
    Check out their open Rust positions at www.ditto.live....
    If you would like to support what I do, I have set up a patreon here: / noboilerplate Thank you!
    All my videos are built in compile-checked markdown, transcript sourcecode available here github.com/0at...
    Corrections are in the pinned ERRATA comment.
    Start your Rust journey here: doc.rust-lang....
    CREDITS & PROMO
    My name is Tris Oaten and I produce fast, technical videos.
    Follow me here / 0atman
    Website for the show: noboilerplate.org
    Come chat to me on my discord server: / discord
    If you like sci-fi, I also produce a hopepunk podcast narrated by a little AI, videos written in Rust! www.losttermin...
    If urban fantasy is more your thing, I also produce a podcast of wonderful modern folktales www.modemprome...
    Special thanks to my patreon sponsors:
    - Affax
    And to all my patrons!

Комментарии • 601

  • @NoBoilerplate
    @NoBoilerplate  2 года назад +260

    ERRATA
    - I did not intend for the video to go black in the credits at the end, classic video editing mistake!
    - Not an error, but at 10:50 @edgeeffect said "It's impossible to get the Hoare's back in the stable." which deserves recognition as a decent pun.
    - 7:22 I say 'integer' but I'm referring to a float. I should have said 'number'.
    - 9:26, should be “unwrapping” with two Ps, not one

    • @loganclark3642
      @loganclark3642 11 месяцев назад +2

      At 9:25, it’s should be “unwrapping” with two p’s, not one

    • @NoBoilerplate
      @NoBoilerplate  11 месяцев назад +5

      @@loganclark3642 yeah, or perhaps I should have made it clear I'm talking about the method,
      unwrap()ing
      I think that's probably where the missing p has gone! Thanks!

  • @4teapo
    @4teapo 2 года назад +464

    "Of course, unlike mathematicians, we live in the real world"
    - No Boilerplate

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +75

      A little mean, but you get the idea!

    • @RenderingUser
      @RenderingUser Год назад +10

      my math teacher after seeing this video: ​

    • @RepChris
      @RepChris Год назад +19

      @@NoBoilerplate Honestly i doubt a mathematician would be offended. Math uses and creates many things which (as of current knowledge) arent in the real world. But that also allows them to come up with ingenious mathematical constructs like complex numbers, quaternions, higher dimensions,... that often turn out, a few decades or centuries later, to be integral for some applied thing, be it quantum physics, fluid dynamics, or videogame graphics.

    • @ИванЗакутний-м3ц
      @ИванЗакутний-м3ц 10 месяцев назад

      @@RepChrisIt depends on wtf we are meaning by the "real world".

    • @JosephM101
      @JosephM101 3 месяца назад

      Johnny with his 300 bananas feeling real targeted right now 😂

  • @tylerbloom4830
    @tylerbloom4830 2 года назад +549

    When I try to explain to people why I like Rust so much, I start with how humane the language is. It understands that devs don't have infinite bandwidth and can't keep all possible states and outcomes in their head and gives you tools to handle the "bad paths". Options and Results are the first examples that I use. That design philosophy is ubiquitous in the Rust community, and that makes the language a true joy to work with.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +48

      Exactly! Options and Results aren't even that clever - there's lots of other brilliant features that are revolutionary, but Options and Results do the day-to-day hard work of Rust, don't they!

    • @costelinha1867
      @costelinha1867 2 года назад +25

      Honestly, So far I like Rust merely due to how insanely convinient cargo is for... almost everything I can imagine.
      Hell, it even has a command to automatically format my code. It may not be perfect, but hey, I like it.

    • @tylerbloom4830
      @tylerbloom4830 2 года назад +21

      @@costelinha1867 Oh, there are a ton of reasons to use Rust. Cargo is a fantastic tool. I'm talking purely about getting people to think about how Rust can meet a need they don't know they have.
      Nearly all languages have linters and formaters and tools to be check the soundness of your code. I've found that if you lead with that, they will default to "I already have something like that." Are they as integrated as cargo? No, but they're already defensive. Instead, if you show them a pain you don't have to deal with, you'll pique their interest and can follow up with things like cargo.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +11

      @@costelinha1867 It's pretty perfect! The dependency handling is gorgeous - read up on the package "yank"ing behaviour!

    • @costelinha1867
      @costelinha1867 2 года назад +4

      @@tylerbloom4830 Indeed. It's just that I'm so new to Rust, and so far cargo has been the most noticable thing to me. Specially since I've had a feel... unpleasent experiences with Python's package manager.
      But Rust has so many cool things, as well, but with regards to safety. I never really had to worry much about that. Although in a more serious project or work enviroment it would be great to have it. Part of me is still having trouble imagining programs that can be so safe.
      The only real downside with Rust that I've found, is that most of the libraries I've used are somewhat new, so there aren't many tutorials for me to use, so I have to rely more on documentation. Which for many people is fine, but I have real trouble finding useful information in documentations.

  • @miniminerx
    @miniminerx 2 года назад +260

    That's a way of doing a sponsor ive never seen before and i am 100% here for it. Awesome way to send the call to new hires

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +56

      I'm so relieved! I've turned down a lot of offers for boring advertisers, what I'd like to do is do relevant useful ads that further my goal of increasing Rust's adoption!

    • @minnow1337
      @minnow1337 2 года назад +14

      @@NoBoilerplate The ad read made me subscribe 🤩

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +11

      @@minnow1337 wow! What did you like specifically so I can keep finding good sponsors?

    • @minnow1337
      @minnow1337 2 года назад +23

      @@NoBoilerplate Your delivery seemed genuine and you were transparent about their offering, but mostly the offering itself provides a unique and interesting opportunity that could be extremely valuable to viewers. It’d also tightly related to the subject matter so it doesn’t feel like a major departure from the topic

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +10

      @@minnow1337 Thank you so much! I'm hoping to find other nice Rust companies to point my viewers too - LET ME KNOW IF YOU KNOW ANY!

  • @Kiaulen
    @Kiaulen 2 года назад +62

    I didn't know until I started watching NB that I wanted "fast, technical videos", but man am I hooked. Thank you!

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +8

      My pleasure! I suppose one day I'll have run out of things to say about Rust (I certainly have a long list of other topics) and maybe if the sponsorship stuff takes off I'll have time to make all the videos! What a world!

  • @kim15742
    @kim15742 11 месяцев назад +36

    "Just as in life, worthwhile interaction comes with the possibility of failure", goddamn, you're taking me on a philosophical spiral

  • @sergiopolarbear810
    @sergiopolarbear810 2 года назад +133

    i just want to say that a few months ago i stumbled across one of your videos and it started an entire rust rabbit hole for me. now I've read the rust book and I'm making a sudoku solver in rust for practice! :D

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +22

      Fantastic! This is music to my ears, I started this Rust series to get the word out about this life changing language!

    • @michelfug
      @michelfug 2 года назад +7

      Haha this is the exact path I took a couple of months ago. Getting excited by the videos, reading the book and writing a sudoku solver for practice. Have fun ✌️

    • @alaouiamine3835
      @alaouiamine3835 2 года назад +2

      me too, i just made a tetris clone based in the terminal.

  • @piguyalamode164
    @piguyalamode164 Год назад +31

    The other thing to understand about rust is that the rust book encourages you to think about errors as either recoverable or unrecoverable. Recoverable errors should be Results. Unrecoverable errors should panic. What exactly the difference is is up to the library author, but things that can just fail at random (ie file reads, http requests, ect) should be recoverable. Things that break the contract (such as trying to initialize a type on an invalid value) should panic. Everything else should be recoverable. However, rust libraries(especially the standard one) frequently provide checked alternatives to functions that can panic(ie vec .get returns an option, whereas indexing returns the value but can panic if it is out of bounds). This is why the idea that rust STD panics(and that this is bad and makes rust not suited to certain kinds of tasks) kind of misses the point. Rust STD panics if you choose to use the functions that make you enforce the contract.

  • @theoemeriau3961
    @theoemeriau3961 2 года назад +87

    the crate no_panic works like this :
    - create an anonymous struct that impl Drop
    - the impl Drop call a C function that does not exists
    - create the struct at the function start
    - add std::mem::forget at the end
    - if the compiler prove that the code never panic => never unwind (so mem::forget is always called)
    - the compiler can remove this anonymous struct and the call to the C function
    - if the compiler fails to prove it => the linker try to find this C function and it fails

    • @miguelguthridge
      @miguelguthridge 2 года назад +30

      Damn that's a massive hack but also super smart

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +28

      Wow yeah that's wild! I'm delighted its possible XD

    • @AndrewBrownK
      @AndrewBrownK 2 года назад +14

      Note however panics are not necessarily unsafe or even undefined behavior. Hence the ability to catch panics in code that implements UnwindSafe

  • @creeperkafasi
    @creeperkafasi 2 года назад +46

    Congrats on another sponsor and thanks for the video! I recently decided to use rust by actually writing a few projects that i can complete instead of just mindlessly writing playground projects with no error handling and a bunch of unwrap()'s. Rust just never fails to amaze me with the design choices and gets more fun the more I use it.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +7

      Thank you! Not every video will likely have a sponsor, as I'm only accepting ones that are relevant.
      Did you see my Lightsaber video? Make sure you have a few of those best practice crates in your projects for maximum ergonomics!

    • @creeperkafasi
      @creeperkafasi 2 года назад +2

      @@NoBoilerplate I did! I'll make sure to put those tools to good use at some point :)

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +4

      @@creeperkafasi Amazing! GO FORTH AND CHANGE THE WORLD! (be nice)

  • @glauco_rocha
    @glauco_rocha Год назад +52

    it is just beautiful that the developers of rust think of errors as EXPECTATIONS not EXCEPTIONS
    this is the sort of poetic simplicity that the real programming gurus of all epochs out there are always looking for

    • @NoBoilerplate
      @NoBoilerplate  Год назад +9

      Such a simple shift!

    • @tomtlrech1392
      @tomtlrech1392 6 месяцев назад +1

      So I appreciate I'm necro-ing a 10mo old comment, but I'm not sure where else I'd ask this question and hope for a decent result outside of this comment section:
      In the video, the line was used "next time you are tempted to return "false" or "null" to signify an error state, think about this" in reference to writing code with well-defined expected error states. Can "false" and "null" not be used as "expected" error states for a function, and handled logically by the calling code? This seems to me (novice programmer) like a best-practice issue rather than a language architecture issue.

    • @falconelsu9798
      @falconelsu9798 6 месяцев назад

      @@tomtlrech1392 (1) false or null don't force the caller to deal with the possible error case like Option and Result do. (2) false or null don't convey any information about what failed or why it failed like Result does. (Option doesn't either, but that is why you'll use one over the other sometimes.)

    • @iykury
      @iykury Месяц назад

      @@tomtlrech1392i think the point is that if it's enforced by the compiler, then people are more likely to do the right thing

  • @adamd0ggg2
    @adamd0ggg2 2 года назад +22

    In TS I return errors whenever I can address the error in the calling function. function squareRoot(num:number): number | Error . TS will force you to check the returned value before you can use it. If an error would mean that the function calling it could not do anything useful I like to throw it. It should go to the console as a way for me to debug so it never happens. Or in some cases map thrown exceptions to specific handlers like a specific HTTP status when working on the backend.

    • @climatechangedoesntbargain9140
      @climatechangedoesntbargain9140 2 года назад

      how do you know the calling function is able to address the error? Aren't you making assumptions about code you don't know?

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +4

      Aha, good to know, thank you for telling me!

    • @adamd0ggg2
      @adamd0ggg2 2 года назад +7

      @@NoBoilerplate It is actually thanks to a previous video of yours about Rust match cases that I decided to implement that design where I could in TS applications.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +2

      @@adamd0ggg2 fantastic! TS is great if you have to work in a javascript environment. But I dream of yew.rs

    • @adamd0ggg2
      @adamd0ggg2 2 года назад

      @@NoBoilerplate I love TS. I've done a hello world with yew. Frontends are by far the most complex state systems I deal with in programming. Low level rust efficiency isn't appealing to my 100% cloud and container based team. But to never have an invalid state...........

  • @Elliot.2591
    @Elliot.2591 2 года назад +3

    congrats on the sponsorship!! i have covid and your videos are very relaxing :)

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      BAD LUCK! All the best for your recovery, I'm glad my videos are relaxing, if you run out of them there are 9 seasons of my scifi podcast you could listen to! ruclips.net/video/p3bDE9kszMc/видео.html

    • @Elliot.2591
      @Elliot.2591 2 года назад

      @@NoBoilerplate bet :) ty

  • @andredasilva6807
    @andredasilva6807 2 года назад +5

    since i started to use go for more than a day, I realized errors should be handled directly. its more work in the beginning, but you gain so much control and clarity. I use python at work, but I started to really dislike exceptions. I often end up checking code from 3rd party packages just to see what could be a possible exceptions. its quite annoying. and i think rust made it even nicer to handle errors with the Result enum.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +3

      I've heard it's a terrible time fasterthanli.me/articles/i-want-off-mr-golangs-wild-ride

  • @MithicSpirit
    @MithicSpirit 2 года назад +15

    Monads, like Option/Result (or Maybe/Either as they're usually called in FP), are one of the best ways to abstract away impurities in code. While these examples (the ones shown in the video) only account for handling the impurity of partial functions, other Monads can also abstract other impurities into a pure interface, like IO abstracting away side effects.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +9

      Found the Haskell developer! I kid, I kid. I love Haskell and I'd be using it if I thought I could get paid to write it. My journey to Rust started in Haskell (via Scala and Clojure).
      There's nothing magic about Result and Option, they're both implemented as enums, Rust's sum types. If you wanted to, you could make a purity system like IO in Haskell. However, I don't think people want to.
      What we want is for our code to work reliably, and though you CAN do that with pure functions, you can also do that almost as well with ensuring all Results are handled carefully. It's idiomatic and easy in Rust.
      So while I was sad that Rust didn't have purity, I actually don't find I mind, because what I care about is my programs WORKING when they compile. Rust's there, and it's practical.

    • @MithicSpirit
      @MithicSpirit 2 года назад +2

      @@NoBoilerplate Yup, partial functions are probably most problematic impurity. While IO impurities can occasionally cause issues, I feel like programs-as-proofs would be much more helpful for producing code that works *as intended* (rather than just works but might produce an undesired result), as we have discussed on the discord.

    • @KohuGaly
      @KohuGaly 2 года назад +4

      @@MithicSpirit The problem with programs-as-proofs is that, very often, the hard part is figuring out what the program is intended to do in the first place. That's why vast majority of programs and libraries don't start and end at v1.0. There are post-hoc modifications that don't come from the program having bugs, but from its intended purpose drifting.

  • @JorgetePanete
    @JorgetePanete 2 года назад +3

    Thanks to channels like this I can confidently say Rust may be my next stop after Java, I do like Java a lot but compile-time guarantees like these are very nice

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +4

      Fantastic! Do check out Kotlin on your way, that might be a much nicer way of writing Java for you?
      With Rust, start here fasterthanli.me/articles/a-half-hour-to-learn-rust

  • @apidas
    @apidas 2 года назад +5

    I love watching these propaganda videos

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      The thing with Rust is that it sells itself, it's actually doing lots of new things that come together to make a language we've not seen before outside of academic circles. My job is to just explain this as best I can!

  • @thingsiplay
    @thingsiplay 2 года назад +57

    But there is still "unsafe" Rust code. It is even in the std library and some crates use it. Because without "unsafe" in the background, some things wouldn't be possible.
    The good news is, these are very spare and if something happens badly (like nulls, yes, nulls are in Rust available through "unsafe"), then you know exactly where to look. And that is extremely valuable. The "regular user" shouldn't do anything in "unsafe" Rust anyway, maybe besides in very intense moments for specific hardware like drivers.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +40

      Absolutely, see my "Turtles" video for my thoughts on the matter.
      If you don't have an unsafe system in your language, you force your users to continue writing C extensions. Bad!

    • @PyPylia
      @PyPylia Год назад +5

      Actually, I'd say that the regular user should need to do stuff in unsafe rust, just rarely. Oftentimes when interacting with APIs, especially the Windows API I have to use it. However, luckily it is usually just a couple functions with small bits and pieces wrapped in unsafe blocks, and that's all I need.

  • @PaulSebastianM
    @PaulSebastianM Год назад +2

    Splendid video! Amazing as always! If anyone tries to contradict this video, they're a madman!

  • @thearyanahmed
    @thearyanahmed 2 года назад +6

    "Lets be real, shit happens" - No Boilerplate

  • @carapas_
    @carapas_ 2 года назад +9

    I am glad that this practice become popular in Android development too. Basically, you can use this pattern in many languages: create custom Result class and return it instead of raw value. You won't get rust compiler there, but using Result is pretty comfortable to use.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +4

      Google announced first-class Android support at last week's GOSL event! rewatch here: opensourcelive.withgoogle.com/events/rust-day-2022

  • @bibliophile5863
    @bibliophile5863 2 года назад +2

    TypeScript doesn't have an option object. It does have strictNullChecks, which requires union (rust: enum) types which contain null/undefined to be handled appropriately, but it doesn't feel like an appropriate comparison here, except as another example with null. Perhaps "optional chaining" was intended? It's a huge improvement, but still inferior to rust's Option

    • @NoBoilerplate
      @NoBoilerplate  2 года назад

      Ah apologies, I was thinking of Python's type hints, which are called Options, too. Thank you for the correction!

  • @xdman2956
    @xdman2956 2 года назад +9

    8:30 just before this slide I actually thought to myself "I don't see why you said exceptions break the flow, but claim somehow this is better", so in essence "this looks an awful lot like exceptions"
    I'm so amazed by the video making skills here

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +4

      The trick to this is to practice the script A LOT. I read it out loud all through the editing process, and this encourages natural flow and thoughts like "hey won't people be thinking this looks like exceptions" :-D

    • @gareth2021
      @gareth2021 2 года назад +1

      same thought lol

  • @duwangchew
    @duwangchew 2 года назад +8

    All I see and hear are good parts of rust.
    I'd love to see some drawbacks as well, because no language is perfect.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад

      I'm not the right person to do that kind of thing. HOWEVER you should read everything Amos has ever written fasterthanli.me/articles/when-rustc-explodes

    • @AndrewBrownK
      @AndrewBrownK 2 года назад

      No higher kinded types (despite having higher kinded lifetimes), constantly inventing new syntax for different monads, and the bane of my existence: no type level sets

  • @krishnabharadwaj4715
    @krishnabharadwaj4715 2 года назад +16

    I like that you are not teaching Rust but instead telling why Rust is unique. This is important because we have lots of programming languages doing the same things in slightly different way and syntax. It is also surprising to see that how every language is built on the same principles decided some decades ago like for instance the way they handle errors. Also no programming language has made any attempt to challenge it. Rust might not become the best language which solves every issue of the existing languages (I sincerely hope it becomes) but it still brings in a fresh perspective which will certainly change the way new programming languages or features are created.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +6

      Thank you for noticing, this is intentional. There are many excellent technical Rust tutorials, my speciality is, as you say, pitch why Rust is WORTH the effort of learning!

  • @BenjaminWheeler0510
    @BenjaminWheeler0510 2 года назад +10

    Hey, Python doesn't have null!
    ...
    It has None.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +3

      AttributeError: 'NoneType' object has no attribute 'ohno'

    • @BlueTJLP
      @BlueTJLP 2 года назад +4

      I have tried dating a variable in Python, but then I quickly learned that it simply wasn't my type.

    • @Kiaulen
      @Kiaulen 2 года назад +2

      @@NoBoilerplate This video is on rails, it should be
      NoMethodError: undefined method `ohno' for nil:NilClass

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +2

      @@Kiaulen oh that just gave me deep PTSD XD

  • @chrissaltmarsh6777
    @chrissaltmarsh6777 2 года назад +9

    Brilliant stuff. Having started way back with assembler and then to C, to hit the actual metal, it was a dangerous business. Fair enough, the machines had less CPU power and storage than my phone. Or my hearing aid, for that matter, so that is what you had to work with. I use rust to tinker with raspberry pi wee small machines. It is wonderful. (Obviously, I'm ancient so this is mostly hobby work)

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +3

      I started off on the ZX spectrum, I remember the days! Rust makes me excited to get back and acquainted with the low level machine again, but without feeling like I'm building myself a time bomb!
      Check out this viewer-submitted story for a longer take that I agree with ruclips.net/video/ZFDqh3slQfU/видео.html

    • @chrissaltmarsh6777
      @chrissaltmarsh6777 2 года назад

      @@NoBoilerplate I started on a 'mini' computer, a Nova. Size of a big fridge; patching code on paper tape by hand. Physics machine. My, what a change!. I did love C when I found it; getting at the control and monitor kit for experiments.
      But rust lets you do that, and express it cleaner.
      But, as I say, those machines would have taken an age to rust-compile.

    • @chrissaltmarsh6777
      @chrissaltmarsh6777 2 года назад

      @@NoBoilerplate That story is exact.As soon as I started with Rust, I knew that this had the feel of C but better. I have written C code that is strong and robust, but it takes a lot of effort, and if you're trying to use someone else's - well, watch out. As for C++ Hmm

  • @nicolashumbert8344
    @nicolashumbert8344 2 года назад +8

    Every video, you manage to put words on why this language is so beautiful. Great job as always!

  • @PacificBird
    @PacificBird 2 года назад +8

    The result wrapper reminds me a lot of Haskell's Maybe type. I think working with uncertainty itself as a data type is by far the smartest way to go about it. While I really love functional programming because of how inherent safety is, Rust demonstrates that imperative languages can also truly respect the inherent danger of working with side effects in a meaningful way.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +6

      Love Haskell, I tried to make it my standard language, but the popularity problem is real.
      Rust snuck in a load of Monads and a HOST of other fantastic features from lisp too.
      Haskell + Lisp = Rust !

    • @lezzbmm
      @lezzbmm 9 месяцев назад +1

      @NoBoilerplate i’ve bounced off of making haskell my main language a handful of times
      id never properly investigated rust tho - i always thought it was “a better c” and that ppl who used it a lot were similarly masochistic to c mains
      but i happened across some of yr videos and the way u made the big picture abt getting all the best parts of c, haskell, and lisp (mostly) via unsafe, types, macros respectively
      all at the same time
      w/o gc
      wew
      thank u so much i’m ditching js and as much as i can help it python lmao

  • @kinositajona
    @kinositajona 2 года назад +34

    Make invalid state unrepresentable!

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +9

      THIS IS THE WAY

    • @techpriest4787
      @techpriest4787 2 года назад +9

      In Soviet Rust you do not invalidate. Soviet Rust invalidates you.

    • @0xhiro
      @0xhiro 2 года назад +7

      In Soviet Rust, you don't correct your Rust code. Your Rust code corrects you.

  • @valsistem
    @valsistem 2 года назад +6

    Randomly stumbled on your vids and now I'm forcing myself to learn rust. Quite hard but fun. Keep up this phenomenon Quality vids

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      It's really something isn't it! It is very hard, you might need to come back to my videos to keep your motivation up! You can do it. Come talk to us on the discord server in #newbie-advice when you get stuck!

  • @rundevelopment
    @rundevelopment 2 года назад +4

    > TypeScript attempts to paper over the damage with its own options type [...]
    This is not true. TS doesn't have an option type, TS has unions (not disjoint/tagged unions, but set unions). E.g. if your function returns a string or null, its return type is `string | null`, which is roughly equivalent to `Option` (without lifetimes, obviously). So TS can perfectly track nullability (both `null` and `undefined`) and has done so in my TS projects for years.
    I also want to point out that from a type perspective, unions are actually more powerful than tagged unions. You can create tagged unions in TS (e.g. you can make your own `Option` type), but you can't do TS's unions in Rust (type safe without `Any` that is). This isn't to say that TS's type system is better. It's not sound for one (not due to unions, though).

    • @NoBoilerplate
      @NoBoilerplate  2 года назад

      I think we might be both a victim of ignorance of the other's language!
      I've looked into TS's tagged unions, and they seem like Rust's enums. They're both sum types, no?
      In fact, there is nothing special about Rust's Option type, it's just an enum doc.rust-lang.org/std/option/enum.Option.html
      (same for Results, they're both enums)
      You can do incredible things when you have sum types!

    • @KohuGaly
      @KohuGaly 2 года назад +2

      @@NoBoilerplate Sum types are tagged/disjoint unions. To see the difference consider:
      These are tagged unions:
      enum LeftRight {
      Left(L),
      Right(R),
      }
      Assume A, B and C are different types. Then:
      LeftRight< LeftRight, C> is different from LeftRight< A, LeftRight >
      Also LeftRight is different from i32
      For set union types, their "sum" is associative
      AorB = A | B;
      BorC = B | C;
      AorB | AorC is the same as A | B | C
      (there is no indication whether B came from the AorB or from BorC)
      Also A | A is the same as A.
      If your language has set unions, you can create tagged unions, by wrapping the variants in unique generic wrapper structs:
      struct Left(L);
      struct Right(R);
      LeftRight = Left | Right;
      Because Left and Right are different types, their set union lets you differentiate whether the inner T comes from left or right.
      Rust does not have set union types. They wouldn't work well. To see why, consider, what if you take set union of multiple types that are generic over multiple lifetimes each? Nightmare fuel.

  • @GonziHere
    @GonziHere 2 года назад +1

    Hey, just wanted to say that I now read the rust docs in your voice :D

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      Ha, amazing! I did consider just recording the docs chapter by chapter for those who want to listen to it more passively, but then I crunched the numbers and it'd take WEEKS to record XD

  • @rumplstiltztinkerstein
    @rumplstiltztinkerstein 2 года назад +2

    Wait! I didn't know about #[no_panic]. It's even better than that then. If this will cause an error if there is the possibility of a panic, then it means we can use it for creating incredibly small compiled code for webassembly and embedded devices. We add the #[no_panic] attribute, if there's an error, we update the code accordingly. Resulting in tiny and fast assembly code.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      Why would it make it small? I think there's other optimisations you can make (no std style) for this

  • @nordern1
    @nordern1 2 года назад +12

    Unfortunately, "rust has no exceptions" is a comfortable lie. panics act the same, they can even be caught with catch_unwind. They are clearly reduced thanks to Result type, but the fact remains that any function called might just explode whenever. Even the no_panic macro only helps partially, since it's not part of the signature, and still triggers for panics you have proven to be impossible.
    It also shares the ambiguity of the error type with exceptions. In your example your function just returns a MathError, and the caller has no idea which of them are actually possible. You *can* specify the exact errors, but then your signatures quickly become unwieldy. Worst case lib authors just return dyn Err and you have no idea what to even react to.
    I think rust should allow the Error part of the Result to be inferred. So it can build a massive signature with every error that can actually occur and know them at compile time, without having to write that out manually. But such a thing doesn't exist yet afaik :/

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +11

      Thank you very much for your clear argument. I feel like perhaps you've been out of the Rust community for a year or two? These were problems, but they are not any more! I'm delighted to be able to correct you on all points:
      1. We don't treat panics like exceptions, you're thinking of Go. catch_unwind is an insane thing to use for regular program development.
      2. "any function might just explode whenever" Rust gets us to with 99% of perfection and admits that it is impossible to get closer. I don't ask for more.
      3. My toy maths example is not something you should take as gospel
      4. "Your signatures quickly become unwieldy" sure do, that's why we've all been using crates.io/crates/anyhow for years, this is a solved problem
      5. "lib authors just return dyn Err" that's an antipattern. Lib authors don't do that after they've been exposed to the community hitting them with issues demanding concrete errors. It is up to the api user to decide if they want to dyn Errror or use Anyhow or similar.
      6. "But such a thing doesn't exist yet afaik" -> anyhow is this functionality that you want!
      Phew! I might not be right about all of them, do correct me if I'm wrong :-)

    • @nordern1
      @nordern1 2 года назад +4

      @@NoBoilerplate Thank you for the reply. I indeed haven't checked anyhow out yet. I might try that. Although from what I can see addresses more the "error reporting" issue, not so much the signature problem. Which is definitely important, maybe even more important. But I feel there is more untapped potential for error handling out there, rust just gets us closer than anything mainstream yet :P
      1+2+5. I know unwinding isn't used much, and panics are discouraged. But that's not the guarantee I'd like to have. If anything, hasn't rust taught us that language guarantees are better than conventions?
      3. It's not just your example. The std io functions work similarly, where they return vague error types, often recoverable, but don't actually tell you which errors might actually occur for specific operations, only all errors that might occur in all of them combined

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +3

      @@nordern1 I think you're not quite grokking anyhow yet - it covers all errors and you don't need to change your signature - anyhow::Result covers all errors.
      You're right that Rust gets us closest to anything - I've never said Rust is perfect (only that it lets you write perfect code) - and each release we see STRONG improvements. Oh! you might find that compile times are 10% of what they were since you last tried out Rust - that was a focus for a while 😀
      Results are the way, you will never find the panic handler used in the way you worry about. I too share you interest in safety and correctness - Rust is the closest thing we have! You and I, with the care that we have, can write perfect code.
      3. I'd love an example of this, I'm sure you're right.

    • @nordern1
      @nordern1 2 года назад +2

      ​@@NoBoilerplate Possible, but that's the issue I have with it. It seems to cover *all* errors in one type, which seems to makes it difficult to find out what actually happened, and how you might recover from it in code.
      E.g.: You use File::create("foo.txt"). You get a result type with an enum of all errors of the entire std::io space. Say I can handle AlreadyExists, but what else might occur? What happens when I create a file in a dir that doesn't exist? Do I get NotFound or NotADirectory or something else? The function doesn't tell me. (The docs do, but if docs where a substitute for a type system, we'd all use JS :P )
      Essentially, what I want is there to be some language that does Java's checked exceptions without it being a mess (And without exceptions). That you always know exactly what errors a function might produce and that no function might just randomly blow up. (Not just that it's convention not to blow up)
      I'm still hoping that some language comes up with a smart solution to this once.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +4

      @@nordern1 the compiler knows ;-)
      What you do is you match on the error you know, and handle `AlreadyExists`, then the compiler tells you what other errors you also need to handle - no guesswork!

  • @pedroalonsoms
    @pedroalonsoms Год назад +1

    the intro analogy was so good

    • @NoBoilerplate
      @NoBoilerplate  Год назад +1

      Thank you! I didn't create the "exceptions shouldn't be exceptional" argument - functional languages have been saying this for decades!

  • @nextlifeonearth
    @nextlifeonearth 2 года назад +13

    I disagree that gotos are bad in and of themselves. Their proper uses are simply rare, but there is no better solution given when its use is there. You don't need them in Rust most of the time with the ? operator, but it does affect the efficiency more than a goto would.
    And I disagree that Rust has no nulls. They're not directly exposed to the programmer, but an Option is practically a nullable pointer. It's just abstracted and protected.
    Null wasn't the problem, its interface was and I find that a very important distinction to make.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +11

      you see how the unknown state of the box is inside a safe Option, right? No bare nulls in the safe subset of rust is a HUGE deal, don't minimise it.

    • @KohuGaly
      @KohuGaly 2 года назад +11

      The difference between a Null and an Option is that Option clearly communicates that there is a None variant, and the type system doesn't implicitly assume that the None is not there. In languages with Null, Null can typically replace any value, so any value is implicitly an Option and almost every operation implicitly unwraps it. What happens when you hit Null unexpectedly can range anywhere from getting default results, through exceptions all the way up to undefined behavior, depending on the language.
      Saying that Option is just abstracted and protected Null, is like saying integers are just abstracted arrays of Booleans. To the extend it's true, it's trivial. To the extend that it's profound, it's false.

    • @penguin_brian
      @penguin_brian 2 года назад +1

      Playing devils advocate here: Isn't the ? operator just like a goto?

    • @Tigregalis
      @Tigregalis 2 года назад +4

      @@penguin_brian ? operator is an early return, (essentially desugars to `match fallible_value { Ok(value) => value, Err(error) => return error }`) so it's only a "goto" in the sense that "return" is a "goto"

  • @prdoyle
    @prdoyle 2 года назад +5

    1:53 - Uh, no. Gotos are not bad because they take you out of the normal flow of execution. It's because they make reasoning about a program harder. Dijkstra covered this pretty well in his original paper. Your argument isn't even internally consistent because you present railway-oriented programming at 6:20, which is all about how to take you out of the normal flow of execution, and is completely equivalent to checked exceptions in Java.
    Anyway, I definitely agree with your overall point that nulls suck. New languages shouldn't have them. It was a mistake when Golang did it; we knew better by the time Golang was invented.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +3

      I should have clarified that 'normal flow of execution' is 'function calls'.
      That genius of Results is that they don't change function calls, you're simply returning a Result that either has the Ok() value you want, or an Err() value you must handle.

  • @Robin_Goodfellow
    @Robin_Goodfellow 2 года назад +5

    "The only way we could avoid errors is by not interacting with the real world"
    I'm looking at you, Haskell. Yeah, yeah, IO-Action whatever.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      heh, Haskell has a lot to teach us, but it has a lot to learn before we can use it practically.

    • @qandak
      @qandak 2 года назад +1

      It is practical. And it has a huge package repository with pretty much everything you might need. Everybody can use it right now.
      The problem of Haskell is that if you have an IT background then just learning is not enough, you have many things to unlearn from procedural way of thinking.
      Yes, it's not easy, but... there is no "unsafe" :)

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      @@qandak I love Haskell, the main reason I say it's not practical is popularity, nothing against the language itself. It's not practical for me to build a haskell team, I can't find juniors, I can afford seniors, and there's like 100 in all of London, and they're already making bank in quant XD

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +2

      @@qandak You say 'no unsafe' like it's a good thing. unsafe in rust is like IO, in haskell, - IO functions aren't BAD functions, you have to have side effects somewhere right? unsafe blocks are the same. Direct pointer access is useful (Haskell does it in FFI inside IO functions downloads.haskell.org/ghc/9.0.1/docs/html/users_guide/exts/ffi.html?highlight=capiffi#extension-CApiFFI) but instead of isolating functional purity, Rust isolates pointer operations. They're BOTH really good ideas!

    • @qandak
      @qandak 2 года назад

      @@NoBoilerplate I was trying to "defend" Haskell a little bit in front of people who are not familiar with it, but I know that you are :)
      As for the rest, I fully agree with you, and have nothing useful to add!

  • @DejaimeNeto
    @DejaimeNeto 2 года назад +3

    Gotta say that posting a job ad on an obviously for-enthusiast channel was mindblowing. It seems so obvious now that I saw it, how have I never thought of that?

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      Now all I have to do is get lightning to strike twice!

  • @jabadahut50
    @jabadahut50 Год назад +3

    Your macro video piqued my interest in rust, but this is the video that made me pick it up. A language that is so well-made you can genuinely create programs that you can legitimately say "under normal reasonable circumstances... it's the hardware that caused the crash, NOT the software." is AMAZING to me.

    • @NoBoilerplate
      @NoBoilerplate  Год назад +2

      It's *wonderful* isn't it? Good wording, hardware can cause crashes, not software. NICE

    • @jabadahut50
      @jabadahut50 Год назад +2

      @@NoBoilerplate legitimately brilliant. As an aspiring game dev, the idea that I can make something that cannot crash by any reasonable means dramatically reduces the bug fixing stage of things. It doesn't prevent game breaking glitches but I can atleast know that the game won't hard crash on the players unless their machine is borked. Given the general resiliency of hardware this means that in general, software can be made to rarely crash at all.

    • @NoBoilerplate
      @NoBoilerplate  Год назад +1

      @@jabadahut50 RIGHT

    • @jabadahut50
      @jabadahut50 Год назад

      @@NoBoilerplate Also as a WebAssembly supported language, I'm a tidbit of typescript, some HTML, and some CSS away from being a full stack dev for the web as a side hustle.

  • @uiytt8497
    @uiytt8497 2 года назад +5

    This looks like a MONAD implementation but it's very nice it's there by default

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +7

      Yes indeed, the Either monad, well spotted!
      I tell people that Rust is Haskell and Lisp snuck into the cool kids party in C's clothing :-D

    • @marcing5380
      @marcing5380 2 года назад +1

      @@NoBoilerplate But is there some idiomatic way to compose it, like "for {} yield" in Scala or "do" in Haskell?

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      @@marcing5380 I don't quite understand what you are asking for, could you say more?

    • @marcing5380
      @marcing5380 2 года назад +1

      @@NoBoilerplate To be more precise:
      Usually you have a chain of computation, the result of the current one depends on the previous one. Example:
      parseToInt(someString: String): Either[Error, Int]
      findInMap(key: Int): Either[NotFoundError, SomeRandomType]
      And now you want to extract from the map given a string so you need to apply it in sequence like:
      parseToInt("123").map(findInMap).flatten
      Or:
      parseToInt("123").flatMap(findInMap)
      But this gets unwieldy for longer sequences of computation so e.g. Scala has the following syntax for it:
      for {
      parsed

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      @@marcing5380 I think this is literally the question mark operater pattern:
      let parsed = parseToInt("123")?
      let result = findInMap(parsed)?
      parsed is the right hand side of the either, as is result.
      doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html

  • @SardarNL
    @SardarNL Год назад +1

    Goto's are bad -> exceptions are bad is a bad analogy. There is nothing wrong with exceptions and panic/unwrap is exception handling. There are basically two ways to handle errors predictably:
    1. Wrap the result in a box (Optional)
    2. Stop and unwind until reaching the code meant to handle errors.
    Both options are equivalent. The box option gives you operators like "if the box contains what I want, then apply a function to it and put the result back in the box", chaining the whole success path. With some generalization, you will end up with reactive programming. Both options bring execution to some top-most outer code which will finally open the box and handle the error if there is any or catch the exception. Error handling in both cases is usually the same - delegate option to repeat the action to the consumer.
    But! Boxes do not require language support (most languages include them). However, without syntactic sugar working with boxes is a real pain. Exceptions are always supported by clean syntax (well, Rust did it meh with unwrap, but it is Rust being Rust...), which is why people tend to gravitate towards them.

    • @NoBoilerplate
      @NoBoilerplate  Год назад

      Panic is indeed like a bad exception system, but that's not what we use in Rust, we use the Result system that is baked-in to the standard library and all libraries.
      Panicking is possible to effectively remove from your Rust code, and even, as I showed in the video, prove that crucial functions do not panic.
      Everything's equivalent, that argument doesn't matter. The differences between exceptions and Results-passing are what I'm interested in, and what this video shows.
      Syntactic sugar? Rust supports Result returning using a single character, `?`. That's pretty sweet!

  • @DrIngo1980
    @DrIngo1980 2 года назад +3

    This video is very well done. So much so I had to subscribe immediately. Really great way to introduce even seasoned software developers to Rust's error handling. 👍

    • @NoBoilerplate
      @NoBoilerplate  2 года назад

      Thank you so much! Check out my other Rust videos here ruclips.net/video/Q3AhzHq8ogs/видео.html

  • @ingloriouspancake7529
    @ingloriouspancake7529 2 года назад +2

    Rust on rails would be amazing!

  • @c4llv07e
    @c4llv07e 2 года назад +2

    This is a great example of why everyone should learn -haskell- functional programming! Even if you won't write code in that style, its ideas are sometimes (for me, every time) very useful in other patterns.

  • @jthoward
    @jthoward 2 года назад +4

    Within the scope of a language that uses exceptions, I do rather like how Java handles this. It does still have all of the problems that exceptions provide, but you must (usually) either handle all possible exceptions or explicitly state that a function throws an exception. As opposed to something like JavaScript where at any given moment, you could get any possible error anywhere in the call stack. Java has its problems, but for something as bloated and verbose as it is, sometimes it does have elegant solutions to its own inherent design problems.

    • @FADHsquared
      @FADHsquared 2 года назад

      Unchecked exceptions exist, unfortunately.

    • @penguin_brian
      @penguin_brian 2 года назад

      Years since I programmed Java, so I might be out-of-date, but the two criticisms of how it does it are (a) Runtime Exceptions do not have to be declared, and (b) programmers complained about it becoming excessive verbose. Possibly (b) is due to poor technique in passing all exceptions as is to higher level code - not sure if Java has better techniques to deal with this (e.g. wrapping the exception).

    • @jthoward
      @jthoward 2 года назад

      @@FADHsquared like I said, usually. But hey that’s Java for you

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      Sure, Java's better than javascript here, but that's no surprise.
      Exceptions THEMSELVES are the problem.

    • @jthoward
      @jthoward 2 года назад

      @@NoBoilerplate Oh, believe me I couldn’t agree more. I just find it interesting how much both better and worse Java can be at some of these things.

  • @hongotopiadada7574
    @hongotopiadada7574 2 года назад +3

    Hey there, I love your videos, they are like a small meditation for me! Let me ask you a question, the font you are using, is it a real font or are thous merged >=, #[, and == signes added later on? and could you share the font or thous sings with me? it love to see them in my code

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      Oh have I got a treat for you. The merged giphs are called "ligatures" and there's LOADS of programming fonts that have them built in!
      The font I am using here is Fira Code Nerd Font.
      It's great! But there's loads of options available. Join my discord server and asking people in #programming what fonts they use and you'll get an avalanche of recommendations :-)

    • @hongotopiadada7574
      @hongotopiadada7574 2 года назад

      @@NoBoilerplate Fire Code is what I'm using too... but It seams like I never invested enough time in it! Thank's a lot, I'll dive deeper into ligatures and join your discord!
      Edit: I checked whats wrong with my setup and it seams that my terminal does not like ligatures! will try kittening my self later this day, I think that will help.
      (shame on me for using the gnome terminal)

  • @magfal
    @magfal 2 года назад +2

    Null was not an error, not anymore than inheritance that can go more than 1 level is an error.
    It's not easy to handle for some people but it allows for very elegant code when handled well.
    Rust is one of the better languages for handling null, along with SQL.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад

      I didn't make it up www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/

    • @magfal
      @magfal 2 года назад

      @@NoBoilerplate I'm not saying he didn't say it. But it wasn't a mistake, just a concept that's too powerful for many minds.

  • @WizardofWestmarch
    @WizardofWestmarch 2 года назад +4

    I've always hated how things like network io or parsing to data types throws exceptions in most languages. It is utter nonsense. Exceptions should only be for things like invalid memory access or OOM etc

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      yeah, something catastrophic that has happened. For rust, that's the Panic system, which is very simple (you can catch it once in the panic_handler, I believe).

    • @WizardofWestmarch
      @WizardofWestmarch 2 года назад +1

      @@NoBoilerplate yeah part of why I'm dabbling in rust is the panic system plus sane error handling

    • @xybersurfer
      @xybersurfer 2 года назад

      but most languages don't have a type system sophisticated enough, for returning errors. so i would rather see those languages throw, than to miss an error

    • @WizardofWestmarch
      @WizardofWestmarch 2 года назад +1

      @@xybersurfer eh many languages have generics that allows option. Won't be as memory efficient as rust enums, but the core ideas still work

    • @xybersurfer
      @xybersurfer 2 года назад

      ​@@WizardofWestmarch "many" and most are not the "same". having option types, and being forced to check them by the type system are completely separate issues

  • @emoutraspalavras-marloncou4459
    @emoutraspalavras-marloncou4459 2 года назад +2

    That's why I love the Rust way of coding and thinking. It has taken the good example of Lisp and Haskell. F# also has that future, but it's not totally free of the possibility of crashing since it has a mixed language pattern.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад

      I'm so excited we have a POPULAR language with all these great features in!

  • @creamyhorror
    @creamyhorror Год назад +1

    Honestly, returning errors exclusively as values isn't really a rare thing that Rust stands out in doing. In Golang, returning an error alongside the result is built into the language itself, requiring the programmer to handle any error immediately. In other languages, you can return errors, sometimes as part of a option/union type (error | result) or a tuple (e.g. in C#). It's more that Rust and Go don't offer exceptions, preventing that sort of flow jumping - but even exceptions are handy in certain scenarios, such as for web app that wants to catch any kind of error and fail a request gracefully. (Granted, such errors might be exceedingly rare in Rust.)

    • @NoBoilerplate
      @NoBoilerplate  Год назад

      Go came so close to doing things right. Consider this pattern, which we see everywhere in go:
      result , _ = func()
      How often have you seen the error ignored like this? Go returns errors as tuples, which is not good enough for me.
      It's an approximation of sum types, Rust's Enum type, but it's not good enough. Go does not have Sum types, and so had to use something worse, alas.

  • @parlor3115
    @parlor3115 2 года назад +3

    Idk if it's your excellent narration or Rust amazing error handling that's causing me to tear up

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +3

      Watch a few episodes of my podcast to be sure ruclips.net/video/p3bDE9kszMc/видео.html
      (for science)

  • @lincoquinn7198
    @lincoquinn7198 2 года назад +1

    Hi Tris, sorry if I've misspelled your name,
    rust allows for `#![warn(panics)]` on crate level, which turns possible panics into warnings, instead of failing to build. It's more ergonomic and shows up in your lsp warnings.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад

      I would LOVE this to be true, but I can't find it. Do you have a link? Thank you!

  • @leka1b901
    @leka1b901 Год назад +1

    I just woke up, why am i so interested in this all of a sudden...

  • @michaelschnell5633
    @michaelschnell5633 Год назад +1

    I just did a small Rust project demoing six different methods the language provides for safe error handling and propagation using Result:
    "is_ok()", "match", "let...else", "if let ... else", "unwrap_or()", and "?"
    are there even more ?
    (If anybody is interested, I will upload the code somewhere...)
    -Michael

  • @eccio
    @eccio 2 года назад +2

    Underscore go brrrrrrrrrrr

  • @rid9
    @rid9 Год назад +1

    There is only one way in which something can go right, and an infinite ways in which it can go wrong.

    • @NoBoilerplate
      @NoBoilerplate  Год назад +1

      reminds me of something a university lecture told my class: "You can be as early as you like and be on time, but if you're 1 second late, you're late."

  • @ClaudioBrogliato
    @ClaudioBrogliato Год назад +1

    I can easily see this blowing in my face if my computation has several levels of nested Result return (and lickely VBox), Does Rust have syntactic sugar for dealing with multiple lifts (e.g. the do block in Haskell)? A few code I've seen present patterns similar to JS's callback hell.

    • @NoBoilerplate
      @NoBoilerplate  Год назад +1

      I know what you mean, also like the (->) function in clojure - the first thing that comes to mind is the result.map() function, which you can chain to mutate the value on the left hand side of a Result safely, only unwrapping it at the end doc.rust-lang.org/std/result/enum.Result.html#method.map
      Unrelated, but important: the question "does have rust have syntactic sugar for X" is always "yes" because of macros! :-)

  • @Amitkumar-dv1kk
    @Amitkumar-dv1kk Год назад +1

    isn't it already very similar to exceptions, like yeah rust forces you to handle so do other languages as well, say Java which can have exceptions in it's method signature that forces you to handle it as well, in a similar divide method in Java, you can add the MathException in the method signature that will force you to handle any unexpected inputs including division by zero. You basically are forced to wrap the divide function in a try catch block.
    And with exceptions, the application does not simply have to quit, you catch exceptions and you decide what to do, you can ask for input again, or simply skip this whole step without crashing the application, I don't see any difference at all.
    As for the nulls, yes it's a problem but Kotlin does not have this problem at all, you can explicitly have nulls there but that would be a similar case as having an unsafe block in rust, Java too has a similar function called Object.requiresNonNull() you can give the function parameters to this function in the signature and you're guaranteed to never receive a null.

    • @NoBoilerplate
      @NoBoilerplate  Год назад

      There are 369k results for "kotlin nullpointerexception"
      www.google.com/search?hl=en&q=kotlin%20nullpointerexception
      It's possibly not as solved as you think it is!
      The bottom line is that the JVM DOES have nulls. Kotlin and scala and clojure deal with the nulls in very smart ways, but the only sure way to not have null problems is to not have null in your language.
      Rust never had nulls. What a relief!

  • @keineahnung1919
    @keineahnung1919 2 года назад +1

    Unfortunately exceptions can do one thing that Results can't: Capture OutOfMemory errors. Luckily you usually don't do that very much

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      While true, my understanding is that most programs do not handle this exception. If you're OOM, you have big problems!

  • @ycombine1053
    @ycombine1053 Год назад +1

    Im just starting to look into rust. I was under the impression that it was simply a low-level C or C++ replacement. Coming to find that i was very wrong. It seems to have borrowed some of the best features from some of the strict functional languages (algebraic data types, exhaustive pattern matching, idomatic use of the maybe monad, immutability) but all of this is wrapped up in much more pragmatic package. For those more sewsonrd in rust, am i on the right track with my interpretation?

    • @NoBoilerplate
      @NoBoilerplate  Год назад +1

      You are absolutely right, I'd been a python web developer for 15 years, and I'm not excited by low-level features (though I'm delighted the language has them!) but the high-level features that will make my life SO much better!
      Here's a short playlists of highlights for videos of mine I recommend, for your interest: ruclips.net/video/oY0XwMOSzq4/видео.html

  • @jetseverschuren
    @jetseverschuren 2 года назад +3

    This feels a bit like C's way of handling errors, but the compiler actually checks if you properly handle errors

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      errno stuff?

    • @jetseverschuren
      @jetseverschuren 2 года назад +3

      @@NoBoilerplate I was mainly referring to the return value. 0 (or something like buffer length) on success, and negative on error. Depending on the implementation it either directly return the error (negative int) or you have to look up errno. My main reason for comparison is because you usually check for it with if statements, and stay in the same flow/context, this also allows you to retry or whatever. By directly returning you can more closely mimic the exception behavior. The syntax isn't that nice though, and forgetting to properly check the return value can easily cause weird bugs (often segfaults) your program

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      @@jetseverschuren Yeah, I nearly put something in the video about the similarity! However I don't have enough experience with C/C++ to really know that I'd be doing the right thing!

  • @mikopiko
    @mikopiko 2 года назад +2

    I had hoped this video had some references to Ruby on Rails.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад

      Though it's not got rails' maturity, I really love rocket.rs !

    • @mikopiko
      @mikopiko 2 года назад

      @@NoBoilerplate Interesting!

  • @pitust
    @pitust 2 года назад +1

    at least for me, rust encourages unwrap().unwrap().expect("lol").unwrap() and Arc which are both awful.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      That syntax isn't boilerplate: That syntax gives us superpowers:
      In your example, I see three unwraps and an expect.
      This tells me that your line of code has exactly 4 ways it can panic at runtime. Solutions to this are to handle the errors correctly, perhaps using match, or to bubble up the error to the calling function with ?
      In my code review, I will recommend replacing those unwraps with appropriate safe alternatives.
      We may, after discussion, decide that the risks are very small, and to leave some of them in, perhaps converting them to .expect("reason") with our reasoning captured.
      This same line in javascript looks like:
      doSomething(data[0].name.first())
      Four places it can crash, zero indication it will do so. Further investigation is needed. Enormous context is needed to be safe in other popular languages, zero is needed in Rust.
      ---
      Your Arc tells me that it's a thread-safe type that can be passed around safely, but might be slow due to locking.
      Many other languages use this exact feature in their core types, and you must read the documentation to find this out.
      My channel is called no boilerplate, which is unnecessary code that doesn't add value. Rust has lots of code that give more value than any other popular language. I'm still learning!
      Do check out my other rust videos, perhaps starting with this one ruclips.net/video/Z3xPIYHKSoI/видео.html
      I'd love to know what you think!

  • @alexander58600
    @alexander58600 Год назад +1

    It looks a lot like Java checked exceptions: if you catch it, you don't have and can't to propogate it to the caller. If you don't catch it, it must be in your method signature, just like the Result type. What is the difference, really?

    • @NoBoilerplate
      @NoBoilerplate  Год назад

      The big difference is that exceptions are an exception to the type system.
      Rust's Result type is just a normal Enum, part of the normal type system.
      Because Rust had sum types from the start, there was no need to build an exception system - the type system already has the perfect solution!

  • @marcusrehn6915
    @marcusrehn6915 Год назад +2

    I had not though about rust not having null from the start, but I strongly agree with you.
    Having programmed in Scala, I always felt like the biggest issue there was the fact that you always had to use Java libraries, ridden with nulls. Making the Scala even feel pointless at times.
    Rust is it's own ecosystem, much more than Scala can ever be.

    • @NoBoilerplate
      @NoBoilerplate  Год назад +3

      Exactly, and the same problem happens with Typescript, javascript leaks through.
      Rust is a revolution, and I'm HERE for it!

  • @DNA912
    @DNA912 Год назад +1

    It's always interesting when I look at my rust code and compare it to other languages. It usually feel pretty clean. But most of all. My rust code is just full of enums and match statements, everywhere. And Before I coded in rust, I barely ever used Enums.

  • @RepChris
    @RepChris Год назад +1

    This seems quite similar to the way Go does it, where it returns two values, the result and a possible error, and before using the result you check if the error is nil; if it isnt you handle it in some way, like propagating it up. Although having both be the same return value, just a different type, does lend itself to prevent a lazy programmer from skipping the error check and writing code that can crash.

    • @NoBoilerplate
      @NoBoilerplate  Год назад +1

      Yes, it's a shame Go does it this way. It's MUCH BETTER than using exceptions, however! But Rust's way (ie, Haskell's way etc) is the correct way.
      A sum type (called Result) where the left-hand side is the type you expect, and the right-hand side is the error value.

  • @ColinFox
    @ColinFox Год назад +1

    I understand the problems that people have with Null, but on the other hand, how else do you represent "I don't know"? There are times, particularly when working with databases and user input, or indeed any input from the real world, where you have to represent the value of "I don't know".

    • @NoBoilerplate
      @NoBoilerplate  Год назад +1

      Optional is the solution!
      When querying a database that may or may not have a string or null, in Rust you'd model that as an Option.
      The advantage of this is that you are never surprised, you must always handle the nationality - it's such a relief to always know what you've got! :-)

  • @tim57243
    @tim57243 11 месяцев назад +1

    Another way to crash is with a stack overflow. In recursive code, you might not be able to compute at compile time the amount of stack space required. Do we agree that Rust can't prevent that type of crash?

    • @NoBoilerplate
      @NoBoilerplate  11 месяцев назад +1

      I have great news! Though you're quite right, there's no tail call optimisation in Rust yet, it is planned with the `become` keyword.
      But even better than that, just as with anything, you can have this feature today using the macro system: lib.rs/crates/tailcall

  • @kaidenrogers
    @kaidenrogers 2 года назад +1

    Are you using the same colour as the background of RUclips in dark mode for the background of your video to achieve as seamless video? That's pretty clever

    • @NoBoilerplate
      @NoBoilerplate  2 года назад

      Started by accident, but now I'm keeping it! It's a shade off, if you look closely, your comment has inspired me to make it perfect for the next video!

  • @wanderingthewastes6159
    @wanderingthewastes6159 2 года назад +2

    I was reading the Zig website and one of the things they specifically mentioned about Rust is that standard/common functions can often panic on their own even tho there are/could be situations the dev would want to proceed regardless of a particular operation, so considering this the no-panic seems even more like a godsend.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      I'd love a link to that, Zig is a very well-thought-out language.

  • @rallokkcaz
    @rallokkcaz 2 года назад +2

    Wow the first ad I've ever seen on RUclips that's actually relevant and meaningful to me lol. Thanks ditto!

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      WHAT big shoes to fill, I hope that I can find more sponsors like Ditto, I've turned down lots of unrelated sponsors as I don't want to annoy you!

  • @FlourescentPotato
    @FlourescentPotato Год назад +1

    I highly suggest backing up from the mic a lot more, the ASMR style voice is very uncomfortable :)

    • @NoBoilerplate
      @NoBoilerplate  Год назад

      Thanks for the tip, but as I explain here, I can't afford not to :-D ruclips.net/video/fzNk_1xLIKI/видео.html

  • @Klayperson
    @Klayperson 2 года назад +1

    Java, TypeScript, Ruby: trying to retroactively reduce the damage done by nulls
    C#: nullable value-types!

  • @stejz77
    @stejz77 Год назад +1

    From the title I was expecting framework like Ruby on Rails, but you know, with Rust :D

    • @NoBoilerplate
      @NoBoilerplate  Год назад

      GOTCHA! But yes, I'd love that, current development is really good in the API space, but I'm not aware of ones that have Rails' scaffolding generation, that'll be great!
      Here's my video on my recommended rust web stack, btw: ruclips.net/video/pocWrUj68tU/видео.html

  • @felixbaker8709
    @felixbaker8709 2 года назад +1

    At 2:35 you said that unlike mathematicians, we live in the real world. As a mathematician, I can assure you that we too live in the real world. :)

  • @wdwdHenry9022
    @wdwdHenry9022 2 года назад +1

    I dont know anything about programming do you recommend learning rust before anything else?

    • @NoBoilerplate
      @NoBoilerplate  2 года назад

      Even though people say Rust is very different to other popular programming languages, most programming languages are very similar. There's no risk in picking the 'wrong' one.
      If you get half-way through learning Rust and realise you'd rather switch to Javascript, Python, or Ruby (three very popular languages I'd also recommend) you'll have learned VERY transferable skills!
      The Rust Book is very easy to get into doc.rust-lang.org/stable/book/
      And the exercises in github.com/rust-lang/rustlings are WONDERFUL and start extremely simple.
      Both these resources are something I'd recommend to anyone new to programming.
      And if you'd like help, either Rust or whatever language you choose, ask questions in #NewbieAdvice on my discord server (links on noboilerplate.org/) I would be delighted to help you further, and if I'm not around, so would one of the many lovely people on there :-)

  • @BenjaminGoldberg1
    @BenjaminGoldberg1 2 года назад +1

    The way no_panic apparently works is hilarious :)

    • @NoBoilerplate
      @NoBoilerplate  2 года назад

      I don't QUITE know how it works, but it does!

  • @vxqr2788
    @vxqr2788 2 года назад +2

    Wow, truly awesome work. Short, technical and to the point. And on top of that, caused some sparks of enthusiasm inside me to give it a try.
    P.s I am writing all this to support the channel. 😀

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      You are so kind! Rust is REALLY exciting to me, and that's why I just HAD to start this series!

  • @Noah-cf6zd
    @Noah-cf6zd Год назад +1

    This is a great video but very annoying because my pc keeps crashing for unrelated reasons when i’m running my rust program haha

    • @NoBoilerplate
      @NoBoilerplate  Год назад

      Ha! Bad luck - it could be out of memory errors if you're compiling large projects with not much ram?
      Try closing your browser while compiling as a test XD

  • @Blaineworld
    @Blaineworld Год назад +1

    1:49 Because it’s an “exception!” /j

  • @sigstackfault
    @sigstackfault Год назад +1

    Unfortunately, causing the box to get hotter is a type of I/O because it might cause you to get OOM killed

    • @NoBoilerplate
      @NoBoilerplate  Год назад

      Yes indeed. There's a strict line in Rust where the language doesn't attempt to handle hardware problems gracefully.
      Instead of wrapping OOM or divide by zero etc in an exception system, or in rust's native Result system, it panics.
      If the CPU or memory has gone wrong, you're getting a panic.

  • @Dazza_Doo
    @Dazza_Doo Год назад +1

    0:00 - 0:45 Functional programmers running only pure functions on their devices.
    Function peep 1"My Functions are so pure, it's cleaner than water".
    Function peep 2 "I'm so jealous, mine is full of Side Effects, Hey Peep 1 what does your Function do on that gaming machine, something cool?"
    Functional peep 1 "Oh it's Soo Cool ... With running so many CPU cycles and removing the fans, you never have to worry about being cold again" 🔥

  • @josegabrielgruber
    @josegabrielgruber 2 года назад +2

    Working with null had teached me to be a pessimist developer, assuming everything will be wrong at first.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад

      Thank you for your service. You may now retire into the green pastures of Rust. The water's fine!

  • @Jasonwynn10
    @Jasonwynn10 2 года назад +1

    Tor is being remade in Rust! The project is called Arti. What are your thoughts?

    • @NoBoilerplate
      @NoBoilerplate  2 года назад +1

      Saw it a few weeks back on HN - I tried it and it worked out of the box, just a cargo install away! Fantastic!

  • @RandomHandle120
    @RandomHandle120 Год назад +1

    So Rust's error handling system is effectively the same as Java's checked exceptions, minus the actual exceptions. Java's checked exceptions always received a bad rap in the developer community; I never understood why. I always found checked exceptions very useful in alerting me at compile time what could go wrong. I'm glad that Rust in its own way is also enforcing error handling like Java did.

    • @NoBoilerplate
      @NoBoilerplate  Год назад

      I'm afraid this is not the way I see it, do re-watch my video again.
      I know the `?` operator makes them feel similar to checked exceptions, but they are not the same.
      The problem with exceptions is that they take you outside of the normal function/method call flow of programming and on to a new flow: try/catch.
      This complexity is not worth having in a language.
      If your language doesn't have sum types (ie something to build the Result type) you have no option but to build it in.
      If your language has sum types, you don't need to build an exception system.

    • @RandomHandle120
      @RandomHandle120 Год назад +1

      @@NoBoilerplate My comment was not so much about exceptions vs `Result` types, and more about the "checked" in checked exceptions in Java. I honestly feel that exceptions are still a better approach than the `Result` type for a couple of reasons, but that is beyond the scope of my comment.
      What I do have a strong opinion on, is that the compiler should force the developer to deal with potential recoverable errors. Java does this by ensuring that the developer either catches or throws the checked exception up the stack. Rust does this by ensuring that the developer either deconstructs the `Result` type or returns it back up the stack. Contrast that to what C# does, for example: a method can throw an exception the program could easily recover from, but you will not find out unless you go out of your way to dig through the method's documentation, or later at runtime at 3AM on a Saturday night.

  • @archeryo5218
    @archeryo5218 Год назад +1

    What did you mean by "Java now has options" when referring to handling nulls?

    • @NoBoilerplate
      @NoBoilerplate  Год назад

      I'm not an java expert but people have told me that Java has various types for handling nulls, eg: docs.oracle.com/javase/8/docs/api/java/util/Optional.html

  • @francisking708
    @francisking708 2 года назад +1

    Also see optional in C++

    • @NoBoilerplate
      @NoBoilerplate  2 года назад

      Yeah! I first saw Options in Scala (though I am sure they existed many places before then)

  • @Whatthetrash
    @Whatthetrash Год назад +1

    I have a question. I new to Rust and I downloaded the no-panic crate ('cuz it sounded awesome) and added it as a dependency and then tried it out. I can't get it to work. Am I missing something? Here's my code:
    use no_panic::no_panic;
    #[no_panic]
    fn demo() -> i32 {
    42
    }
    fn main() {
    println!("{}", demo());
    }
    When the code is run, I get this error:
    ERROR[no-panic]: detected panic in function `demo`
    The function takes no parameters and literally just returns 42. How could this panic?

  • @DarkCloud7
    @DarkCloud7 Год назад +1

    Scott Wlaschin made me understand Monads.
    No really.

  • @KingJellyfishII
    @KingJellyfishII Год назад +1

    I'm interested in what people would think of exceptions if you had to define exactly what exceptions could be thrown from a specific function, because then it would give almost as much information as returning a Result and using ? in rust.

    • @NoBoilerplate
      @NoBoilerplate  Год назад

      That's actually how java works, as far as I know:
      public function throws X Y Z
      It's not the explicit function signature that is the genius of the Result type in Rust. It's that the signature affects how you can CALL the function.
      It's perfectly possible to write (say) python code that happily ignores the fact that exceptions may occur. When you get them, you wrap the dodgy call in a try: except block.
      In Rust: You can't even PRETEND that the error doesn't exist, Rust forces you to handle the error cases up front.
      More work, certainly. But this is key to the ability to FINISH writing Rust projects. Once it compiles, it works.
      I talked about this here: ruclips.net/video/Z3xPIYHKSoI/видео.html

    • @KingJellyfishII
      @KingJellyfishII Год назад

      @@NoBoilerplate Thanks for the detailed response! As far as I could see from a quick search, Java sometimes requires you to declare that a function `throws` an exception but not if it's a RuntimeException (WHY?!?). Or something like that. I guess you could make a syntax where functions throwing an exception must be called differently but then exceptions become basically the same as rust Results but with extra steps.
      I wonder how this would apply to algebraic effects, since they have similar behaviour to exceptions and have often been quoted as "monads 2.0", but seem to be lacking some of the good features you've talked about.

  • @tudbut
    @tudbut 2 года назад +4

    rusty rails.

  • @paulkre
    @paulkre 2 года назад +2

    I know this is not what the video is about, but a Rust framework that could replace Ruby on Rails would be cool. :)

  • @idiomaxiom
    @idiomaxiom Год назад +1

    Imagine a generation of engineers who have no idea what null is or errors caused by it.

    • @NoBoilerplate
      @NoBoilerplate  Год назад

      What a success that would be! Your comment reminds me of xkcd.com/378/
      Here's my take:
      Imagine a generation of drivers who don't know how to drive cars without automatic transmission.
      Imagine a generation of drivers who don't know how to drive cars without anti-lock brakes.
      Imagine a generation of drivers who don't know how to start a car without a push-start engine.
      Imagine a generation of drivers who don't know how to ride a horse.
      The definition of progress is that you should have an easier life than your parents, and your children should have an easier life than you. If not, what's the point? :D

  • @fixpontt
    @fixpontt 2 года назад +1

    so basically every time a fuction can fail Rust gives you back a type something like (in c++) std::variant type safe union where you have to check if the result is real or error every time you call the function? do i understand correctly?

    • @yondaime500
      @yondaime500 2 года назад +1

      Yes, although it gives you a lot more options to work with or propagate the Result, compared to what you would have to do with a C++ variant. Trying to replicate this in C++ would probably be a nightmare.

    • @NoBoilerplate
      @NoBoilerplate  2 года назад

      You've got it. Now imagine a language built from the ground up with only that pattern for error handling and no nulls anywhere.

  • @sivaramakrishnanr.7173
    @sivaramakrishnanr.7173 Год назад +1

    pov : rust just got std::optional
    sry i didnt see the ? part rust is cool

    • @NoBoilerplate
      @NoBoilerplate  Год назад

      There's SO many great features as well as the Result type! Check it out: ruclips.net/video/oY0XwMOSzq4/видео.html

  • @arielalon4156
    @arielalon4156 7 месяцев назад

    How would you define n -> 1 / n, isn’t n=0 an Exception?

  • @Randych
    @Randych Год назад +1

    I think that to account for what you described at 10:14 one should instead use Rust's ground-shattering superpower called should_panic test, which blows (up) my mind to this day.

    • @NoBoilerplate
      @NoBoilerplate  Год назад

      should_panic tests for panics at runtime, in a test.
      no_panic is a macro that ABORTS COMPILATION if the code inside the annotated function has any pathways that could panic.
      It won't even *compile*.
      I agree should_panic is great, and a good part of your testing strategy, but it's just re-writing the panic handler during your test run, nothing fancy there.
      no_panic hijacks the linker such that it won't link your code if there are any execution paths that might panic (even if they never would at runtime).
      It's *wild*!

    • @Randych
      @Randych Год назад +1

      @@NoBoilerplate I don't think that's a good idea since panic (as I see it) is a part of Rust for a reason and it's okay to panic if it's intended.
      Maybe I'm missing something here.

    • @NoBoilerplate
      @NoBoilerplate  Год назад

      ​@@Randych I think you are, that's the opposite to the point I put forward in this video. With care, it's easy to write rust that never panics - that's great!