This is perhaps the greatest feature of modern programming languages.

Поділитися
Вставка
  • Опубліковано 1 січ 2024
  • The last 15 years have been a fantastic time to be a software developer. One such feature that we've seen from modern languages has been null safety, which has helped to solve perhaps the greatest cause of runtime issues.
    In this video, I take a look at what null safety is and why it's important.
    Become a better developer in 4 minutes: bit.ly/45C7a29 👈
    Join this channel to get access to perks:
    / @dreamsofcode
    My Gear: I get a commission every time you purchase a product through my affiliate link below. No extra cost to you.
    Mouse: amzn.to/42090tB
    Keyboard: amzn.to/3tSZFag
    Steam Deck: amzn.to/3RPVxQt
    Join Discord: / discord
    Join Twitter: / dreamsofcode_io
  • Наука та технологія

КОМЕНТАРІ • 410

  • @IgorStojkovic
    @IgorStojkovic 5 місяців тому +133

    Few people mentioned how C# has good null handling but I see many are not clear what it does. If you have nullable enabled in your project you will get compile warnings if you use a nullable without checking it first. But you can also configure project to report those warnings as errors. Using the ! operator is like using unwrap in Rust.
    It is also the only implementation of such a feature that doesn't use generics. There is a generic Nullable in C# but it is only used for value types. Nullable support for reference types is just baked into the language.

    • @dacomputernerd4096
      @dacomputernerd4096 5 місяців тому +15

      It also has the null chaining the video describes as well, using the ?. syntax, plus a ?? operator, which is analogous to java's Optional.orElse() function, which is nice to have

    • @Gameplayer55055
      @Gameplayer55055 5 місяців тому +28

      I can feel that C# has everything that other langs are missing
      An *adequate* language must have: trycatch(Rust?), null safety(python?), event system(java?), async with threads(js and python?), native generic types(java?), LINQ(unique to c#), Unsafe, dynamic, a normal debugger instead console.log
      Do you want to connect to a db? SqlConnection
      Do you want to distinguish american and european dates? DateTime.Parse and CultureInfo
      Do you want JavaScript alike dynamic programming (useful for json)? dynamic and ExpandoObject
      Meanwhile it's open source and licensed under a MIT licence, available for linux, macos and mobile, definitely faster and safer than interpreted garbage and can be compared only with java and c++

    • @jocketf3083
      @jocketf3083 5 місяців тому +22

      ​@@Gameplayer55055If you like C#, that's fine. Dismissing everything that isn't exactly like it is pretty silly though. Many of the things you listed have alternatives in those languages, but work in a slightly different way. They are often intentionally different as a feature, not an omission.

    • @Gameplayer55055
      @Gameplayer55055 5 місяців тому +6

      ​@@jocketf3083
      Some languages have really fatal flaws:
      1. java has no unsigned values and structs - pain in the ass to make a socket server
      2. lack of try catch in rust/golang and you call them mainstream after that. thats a step back down to ANSI C
      3. js being single threaded
      4. inconsistency in build systems (c++ and java SUCK)
      I've realised, it's acceptable to call bugs features in a dev community. But come on, sometimes it's too much (I like c++, c# and js for yearly innovations that add MUCH)

    • @sodiboo
      @sodiboo 5 місяців тому +15

      ​@@Gameplayer55055What exactly do you want from "try/catch" that Rust doesn't have? It's basically just checked errors. You definitely can have try-like semantics with the try operator (spelled as a question mark "?" postfix operator), and for the catch-site you use a match statement. With rust, you can't really unintentionally ignore an error. With something like go, however, you totally can. Go has no adequate error handling, but for Rust i think ADTs have the job handled and no explicit support beyond some syntax sugar is really necessary. Even so, if you think stack unwinding with unchecked errors is an essential feature of C#, you kinda can do this with `catch_unwind` and `panic_any`

  • @cleavesolais
    @cleavesolais 5 місяців тому +178

    You focused a lot on how Optionals work, but you totally missed the most important part: In a null-safe language, null is not a valid value for most types.
    This key property is the basis for actually being able to implement null safety at compile time.
    Optionals, where null (Nothing, Empty, ...) is allowed, are just needed in the (rare) case that we want something to be nullable.
    In a language that is not null-safe, say Java for example, you could assign null to an Optional.
    This of course defeats the whole purpose of using Optional, and your static-analysis tool of choice will probably scream at you, but there is nothing in the language that will prevent you from doing that.

    • @musicalintuition
      @musicalintuition 5 місяців тому +2

      What's wrong with an Optional value that is null? I could think of some cases in a database record where a distinction would be made between "None" and a value of "null".

    • @Amejonah
      @Amejonah 5 місяців тому +6

      @@musicalintuition In Rust, you can just wrap them again (in some cases, it will be still small, as it can use niches). Kotlin has sadly not that feature, as you cannot have a nullable of a nullable, so you will still need a wrapper type.

    • @cleavesolais
      @cleavesolais 5 місяців тому +22

      @@musicalintuition The whole idea of null-safe languages is that
      a) values of most types cannot be null (Nothing, Empty, ...)
      b) for those types where null is allowed (Optional, T?, Maybe, ...), the compiler forces you to handle the case of null so that no null-pointer exception or similar can happen at runtime.
      Even in a language that is not null-safe like Java, most programmers will implicitly assume when they see "Optional" that a) the optional itself cannot be null and that b) if the optional is not empty, then it contains a non-null value. (In Java, b) is enforced via a runtime check, while trying to violate a) at least gives you a warning in most IDEs.)
      Using an Optional that can be null might make sense from an implementation standpoint, but it will screw with that intuition and easily lead to bugs.
      If you need to distinguish various types of failures, it makes sense to either define your own type for that or use a type like Either that supports it out of the box.

    • @musicalintuition
      @musicalintuition 5 місяців тому

      @@cleavesolais Thanks for your answer.

    • @adambickford8720
      @adambickford8720 5 місяців тому +5

      Nothing will save you from stupid.

  • @TAP7a
    @TAP7a 5 місяців тому +14

    I love demonstrating the Rust Option type. Because really it is just the enum { None, Some(T), } under the hood, just with a load of interface definitions and what amounts to documentation thrown on top

  • @Christian-op1ss
    @Christian-op1ss 5 місяців тому +281

    IMO Kotlin does null safety best, as it recognizes that this should be a language feature and mandatory. It also has the best syntax for it because of it.

    • @isometric_shahil
      @isometric_shahil 5 місяців тому +10

      How would you compare Kotlin's null safety with Dart's null safety?

    • @Christian-op1ss
      @Christian-op1ss 5 місяців тому +10

      @@isometric_shahil I mentioned Kotlin since it was referenced in the video, but null safety in Dart 2 and up is really similar to how Kotlin does it. However there are still unsound null safety libraries since Dart 1 was not null safe. But basically with modern code I'd say it's really similar, since it's also a language feature with very similar syntax.

    • @Y-JA
      @Y-JA 5 місяців тому +65

      Best would be Rust, not just when it comes to null safety but all sum types that are enum derived

    • @kanauvist
      @kanauvist 5 місяців тому +13

      no, swift does it better

    • @Soromeister
      @Soromeister 5 місяців тому +23

      It's actually English that does it better than any of these.

  • @marekful
    @marekful 5 місяців тому +27

    Nice vid thanks. While typing is optional in Python, it has had ‘typing.Optional’ for a while and there was ‘Union[SomeType, None]’ before that.

    • @jackgenewtf
      @jackgenewtf 5 місяців тому +8

      Was going to point this out. If you use typing (Python's static type checker) null (or None) safety is pretty good.

    • @jackgenewtf
      @jackgenewtf 5 місяців тому +9

      Starting Python 3.10, you can also write it as "SomeType | None".

  • @jp46614
    @jp46614 5 місяців тому +14

    Do note that the way that memory allocation is done, just reading one byte off of the memory you're "allowed" to read will likely not cause a segv but it will be permitted because memory is allocated in size of pages, so protection features only extend to pages. But most software/operating systems know this so they add lots of guard pages in between to catch as many out of bound reads as possible to make debugging a lot easier.

    • @Daniel_WR_Hart
      @Daniel_WR_Hart День тому

      Thanks, I could have sworn that I've read slightly outside of C++ arrays before, but without having a seg fault

  • @LarryGarfieldCrell
    @LarryGarfieldCrell 5 місяців тому +8

    Safe navigation has been in in PHP as well for several years now. It's worth mentioming, given that it's far more widely used than Ruby, for instance.

    • @xeridea
      @xeridea 4 місяці тому

      Yeah, PHP having the null safe operator is amazing for keeping code neat. Gone are the days of mindless null checks. Combined with the null coalescing operator, it (basically a null safe ternary operator), coding has become much cleaner. Null safe operator is especially handy in Blade templates in Laravel.

  • @adamszalkowski8226
    @adamszalkowski8226 5 місяців тому +97

    Totally agree with you on Go... Easy to learn, love the absence of colored (async) functions, but the missing null safety makes my code crash a bit too often for my taste.

    • @ttuurrttlle
      @ttuurrttlle 5 місяців тому +1

      I don't follow go's development closely so idk if they have any plans to add to this, but I see people complain about this on reddit frequently. I wonder if people are vocal enough about it that the go team might address it somehow.
      Go did recently add generics, which the video claims is important to this feature, so maybe it will come soon.

    • @marcusrehn6915
      @marcusrehn6915 5 місяців тому +11

      And the lack of map, fold, reduce, filter and find.

    • @dreamsofcode
      @dreamsofcode  5 місяців тому +32

      Fully agree with you. This video started as a complaint about it, but I decided to spin it as a more general video about null safety.
      I'm going to do another video on looking at Null safety within Go and implementing it from scratch.

    • @infastin3795
      @infastin3795 5 місяців тому +2

      ​@@ttuurrttlleIt won't happen

    • @OldKing11100
      @OldKing11100 5 місяців тому +10

      @@ttuurrttlle I'm an avid Go dev and I would kill for ?(return err) or !(panic).
      Something like:
      file, err := os.ReadFile()
      if err != nil {
      ..return err
      }
      To:
      file, ? := os.ReadFile()
      Would make me incredibly happy.

  • @md.redwanhossain6288
    @md.redwanhossain6288 5 місяців тому +4

    C# has the most matured null handling with plenty of operators, extension static methods.

  • @ilu1994
    @ilu1994 4 місяці тому +3

    0:43 "Writing to a memory address that belongs to another process" That's not really a thing. The addresses in your process are virtual, meaning the kernel maps them to an actual address of your hardware. A address can really only be mapped or unmapped (or protected, but let's ignore that for now) for a given process. Thus, the same address can be used in multiple processes to map to distinct locations in your memory, or even the same ones to save memory for identical segments (i.e. when using fork, or linking the same dynamic libraries). Your CPU contains a little chip called the MMU that translates these addresses on-the-fly as instructions execute. It's an incredibly cool concept.

  • @kxhu
    @kxhu 5 місяців тому +42

    in C# we have ? and ! and the compiler shows you whenever you create something null.

    • @BlazingMagpie
      @BlazingMagpie 5 місяців тому +3

      Maybe I'll get to see it in my career one day...

    • @ripple123
      @ripple123 5 місяців тому +7

      there is also the null coalescing operator ?? and its assignment version ??=

    • @michawhite7613
      @michawhite7613 5 місяців тому +1

      If only libraries could actually take advantage of it

    • @agedvagabond
      @agedvagabond 5 місяців тому

      But it doesn't catch errors until runtime. Even the really obvious ones where u look at your code and go 'duh, I'm an idiot' 😅

    • @ianmarteens
      @ianmarteens 5 місяців тому +2

      @@agedvagabond when Null Reference Types is activated, the compiler checks nullability for you.

  • @TheIppoippo
    @TheIppoippo 5 місяців тому +9

    Another engineer here who uses both Go and Kotlin (with a general preference for Go).
    Yeah, optionals at the language level would be awesome in Go.
    It's annoying because when you generate the Go server/client code from a protobuf specification, it comes with "getX" functions that have rudimentary nil safety built in (ie. x.getY().getZ() will return nil if either x or x.y is nil). Sure, you can write that code yourself, but it's useful that protoc creates the boilerplate for you.
    But it't just not as good as the real thing, like in Kotlin.

  • @MonochromeWench
    @MonochromeWench 5 місяців тому +27

    A good reason to use Typescript rather than just pure Javascript. The Typescript compiler is nice as a sanity checker and with editor support it will highlight your nulls as you type.

    • @etherweb6796
      @etherweb6796 5 місяців тому +3

      There is no good reason to use TS instead of JS.

    • @Tienisto
      @Tienisto 5 місяців тому

      ​@@etherweb6796VSCode is written in Typescript

    • @NatoBoram
      @NatoBoram 4 місяці тому +13

      ​@@etherweb6796Thanks for telling us that you're unemployable but that wasn't the point we were discussing

    • @etherweb6796
      @etherweb6796 4 місяці тому +1

      @@NatoBoram Obvious troll is obvious. Here's a troll snack: TS type guarantees are zero once transpiled and the excess syntax doesn't make code any clearer.

    • @adambickford8720
      @adambickford8720 4 місяці тому

      @@etherweb6796 gl with your 'career'

  • @giorgiobarchiesi5003
    @giorgiobarchiesi5003 5 місяців тому +14

    Good video, thanks for having stressed the importance of null safety. I am using rather heavily C# on some projects, and Dart on some others. The fact that they are both type-safe and null-safe helps me a lot in writing code that runs correctly right from the start, or after very little debugging. On the contrary, javascript is a real nightmare to me.

    • @sef-kc9vk
      @sef-kc9vk 5 місяців тому

      i dont like him.

    • @giorgiobarchiesi5003
      @giorgiobarchiesi5003 4 місяці тому +2

      Speaking of null-safety in C# and Dart, there is a relevant difference between the two when it comes to dictionaries/maps. In C#, accessing a Dictionary with a non-existing key causes a run-time exception. No warning at edit/compile time. In Dart, on the contrary, accessing a Map with a non-existing key gives null. The return value is therefore considered nullable, and the null-safety mechanisms point out the potential error at development time. I like this.

  • @obuqwe
    @obuqwe 5 місяців тому +2

    does lua do this too?
    if you referance an unnasigned variable, it returns a nil value.
    and you can do ternaries ( newvar = array[some_index] or "default value" ) with the said nil
    (sorry if i misunderstood, im reletively new to programing ^^;)

  • @gyuyoungpark5509
    @gyuyoungpark5509 5 місяців тому +6

    The same question came from the reddit golang community. even though i really love golang, I really wish golang have the null safety feature as like kotlin at compile time.

  • @henryfleischer404
    @henryfleischer404 5 місяців тому +3

    I like it when people mention Ruby, it's my favorite programming language. Most of my actual work is in C#, but I use Ruby in class at my college, because I can code along with the teacher's C# and explanations in real time.
    Anyway, I've never interacted with this feature or had a need for it. Someday I probably will though.

  • @vsolyomi
    @vsolyomi 5 місяців тому

    FINALLY something comprehensive on the topic! Thanks!

  • @KaiDoesMineCraft10
    @KaiDoesMineCraft10 5 місяців тому +9

    Swift has a handful of neat things with optionals, you have optionals that you can force unwrap whichll throw errors (!), the chainable optional operator (?). And also stuff like coalescing that sets the variable to some default if the variable is nil (??). You can also declare a variable in an optional unwrap in an if-statement conditional so that the block won't execute if the optional is nil as a method of safe unwrapping

    • @dreamsofcode
      @dreamsofcode  5 місяців тому +3

      The defer keyword is really awesome as well

    • @ryangrogan6839
      @ryangrogan6839 5 місяців тому +2

      Dart is like this too, it's very nice imho

  • @Bliss467
    @Bliss467 5 місяців тому +2

    Another great feature of these languages is pattern matching and switch expressions

  • @100JAD.
    @100JAD. 5 місяців тому +2

    PHP also added null safety in recent years

  • @khangle6872
    @khangle6872 5 місяців тому +3

    Curious you didnt mention PHP, it had a strict type system, support null safety, but dont support generic

  • @nullptr2124
    @nullptr2124 5 місяців тому

    Dude I absolutely loved this video, but I'd like to ask if you could please mention the name of the editor and theme you're using? It looks really pretty!

  • @darrennew8211
    @darrennew8211 4 місяці тому

    There are languages that use typestate that can equally prevent null dereferences. You're only allowed to dereference a pointer if the compiler can prove you've already tested it for not being null. By using an "optional" type, you push this from typestate into the type system. The advantage of typestate is it allows you to do the same sort of thing for array indexes, evaluating unassigned variables, and so on.

  • @JalisR
    @JalisR 5 місяців тому +2

    PHP also has null-safe operators (optional chaining as described in this video) since 8.0

    • @DemPilafian
      @DemPilafian 5 місяців тому +1

      The good news is that web hosting providers should be offering PHP v8.0 by default sometime around 2050.

    • @JalisR
      @JalisR 5 місяців тому

      @@DemPilafian I've yet to see one where you can't set it yourself to the newest, and where you can't set new customer account defaults as a reseller

  • @milasudril
    @milasudril 5 місяців тому +4

    In C++, optional is more a way to not have to use the freestore in order to get a nullable type. In a sense, std::optional is less safe than a pointer, because a null pointer dereference SIGSEGVS immediately on most platforms, while using `operator*` on an unchecked std::optional will read invalid data. The problem lies in the concept of nullability it self.

    • @Zex-4729
      @Zex-4729 5 місяців тому

      Can you elaborate, I have no idea what you are talking about, maybe give an example.

    • @milasudril
      @milasudril 5 місяців тому

      @@Zex-4729 An optional is a container that stores zero or one elements. One way to implement it would be to use std::unique_ptr + some additional stuff to make fulfill the requirements of full value semantics. In case the optional has no value, the underlying pointer will be nullptr. An unchecked access `operator*` will cause a SIGSEGV and the program crashes.
      Using freestore is slow. Therefore, an std::optional stores its data inline, and uses a "valid" flag. If unset, the optional may contain uninitialized data. Reading it will not cause the process to crash, since the data is stored in a mapped page. Most likely the current stack frame. Uninitialized data may be more dangerous since there could be a crash later. Other consequences includes data leak, or unintentional control flow, that ultimately may lead to a root shell. Notice that this weakness assumes that you use `operator*` and not one of `value()` or `value_or`. The former will throw an exception if the value is not set, while value_or will return a default value. See also en.cppreference.com/w/cpp/utility/optional.
      The comparison assumes that you use an OS with memory protection, and also that it never maps low memory addresses. Linux will by default reserve the first 64 KiB, and will therefore always crash at nullptr address. An interesting side note is that if gcc can figure out that a pointer is always null at the time of dereference, it will generate an ud2 when targeting x86. Probably because it is faster to crash that way than trigger a page table walk.

    • @oracleoftroy
      @oracleoftroy 5 місяців тому

      This doesn't make a lot of sense.
      First, using pointers is not the same as using the freestore. One can always take the address of an automatic variable or pass in null for a simple "optional" type without using the freestore at all.
      Second, yes, optional is a value type and so has all the same issues of value types, including reading random junk if you didn't initialize it properly. But the stdlib implementers usually provide a way to enable runtime checks so that the program errors on unchecked access. This can even be enabled for optimized builds should the safety be deemed valuable, making them even safer than raw pointers.
      But yeah, there is a good point in there. It is something to be aware of and C++ tend to trust the programmer to not do the wrong thing. If you do something unsafe in a release build, you wont have any protection by default and weird things can happen. C++ doesn't do as much handholding as more recent languages.

    • @milasudril
      @milasudril 5 місяців тому

      @@oracleoftroy The worst language with regards to null must be JavaScript. It has two of them in the language. We are lucky that it is run in a safe environment, but native JS would be less safe than C, without ++. The problem with null-ability is that you must check for value validity everywhere if there is no way to have a syntax for fallback, or there is a no fallback. Such checks are dedious and makes the code ugly. And what happens if you fail to do so depends on the language and the runtime environment. You'd better of to never use nullable arguments, but instead, rely on the caller to provide an actual value, and so on, until you get to the point where you must do the check (Missing field in JSON, failed computation...).

    • @jakubl8271
      @jakubl8271 4 місяці тому

      @@Zex-4729 std::optional is stack based, so, contrary to dereferencing null pointer (and ending with SEGV), after calling *optional, memory to read bytes from is available. Only state of that memory is undefined, which ends wit undefined behavior.

  • @gurdevsingh9558
    @gurdevsingh9558 5 місяців тому

    your themeing looks awesome man an you please make a video or tell me what theme, colorscheme, desktop environment you use .

  • @xcoder1122
    @xcoder1122 5 місяців тому +1

    Clang does support NULL safety in C. Instead of `whatever *` you can write `whatever *_Nullable`, which allows this pointer to become NULL and `whatever *_Nonnull` which forbids that pointer to become NULL, whereas `whatever *` in fact means `whatever *_Null_unspecified`, which means it is unknown if that pointer can ever become NULL or not. Also you can write `_Pragma("clang assume_nonnull begin")` at the beginning of a section/file and then all pointers are considered `_Nonnulll` by default, unless otherwise specified; just don't forget to balance that with `_Pragma("clang assume_nonnull end")` at the end of the section/file. When you use these in your C code, the compiler will warn you when you pass a NULL value or a potential NULL value to a function that expects a non-NULL value. It will also warn you when you try to assign NULL (or maybe NULL) to a non-NULL pointer variable. And it will warn you when you try to use a Nullable value without checking it for NULL first if the operation would fail in case the pointer was NULL. And as always with clang, you can tell it to make these warnings errors instead, so your code won't even compile if it violates any of these rules. This feature exists since at least clang 9 (released 2019), current version is clang 17. I never write C code without that. I usually use macros for that, so I can define them to be nothing and the code will also compile on other compilers without that feature, e.g. GCC.

  • @draakisback
    @draakisback 5 місяців тому +4

    Personally like dart and rust's variant of null safety. Rust has the better errror handling in general because exceptions are nonsense, but dart in theory eill eventually have a fully null safe ecosystem.

  • @dacomputernerd4096
    @dacomputernerd4096 5 місяців тому +1

    C# also has null chaining. They call it null propogation though. Also a little more boilerplate reduction with null coalescense. Turns
    val = foo?.bar?.baz; return val == null ? false : val;
    into
    return foo?.bar?.baz ?? false;
    It also has the only non-generic take on optionals I know of. Types don't accept null, unless you flag them as nullable. Nullable types, given the above operators, are a lot like auto-unboxing optionals that need no generics. Plus the compiler knows when one can and can't be null quite well, and will tell you when it needs handling. If it gets it wrong anyways, you can force unwrap with a ! operator

  • @spookyconnolly6072
    @spookyconnolly6072 5 місяців тому +1

    in general Lisp and Scheme nil|empty list/false respectively is not as much of a problem due to not having references or nil as a reference, so its less of a problem as a result. in general it also has more language support such as nil being falsity also its less likely to cause a problem. in clojure there's `some->` which can be used to wrap a null returning function on the offchance it gets sprung during a chain

    • @EskoLuontola
      @EskoLuontola 4 місяці тому +1

      Also in Clojure, most of the core functions handle nil the same as if you passed in an empty collection. Reading a value from a map, but the key is missing or the map is nil? The result is nil. Basically safe navigation as the default. You nearly never get a NullPointerException, even though nils are all over the place. And since nil is such a normal value, you'd always remember to write a test for how your function will handle nil in a graceful manner.

    • @spookyconnolly6072
      @spookyconnolly6072 4 місяці тому

      @@EskoLuontola like seeing `when-let` being a common enough macro in generic lisp projects; aswell as i think `car-safe`, `cdr-safe` (which are the main places for nil-related errors), shows that nil-punning is not as atrocious compared to C/C++/C#/Java and that.

  • @JosephGallagher
    @JosephGallagher 5 місяців тому

    I didn't know JS had this "?." thing, it makes it so much easier to verify properties are met

  • @HansBaier
    @HansBaier 5 місяців тому

    Is the editor neovim? Setup looks great. What plugins are used?

  • @redestroyer7994
    @redestroyer7994 5 місяців тому

    I've done my own null-pointer safety by creating a function that takes a pointer and an action (lambda or function). If that pointer wasn't null, then it is passed as the parameter to the passed action and the action is performed

  • @niko-pp
    @niko-pp 5 місяців тому +12

    The pipe operator is the best thing ever and In all of the languages and frameworks I use I implemented it in one way or another if it didn't exist already. It makes writing and reading code so easy imo.

    • @yash1152
      @yash1152 5 місяців тому +1

      how do u implement it in langs where it doesnt exist?

    • @sufilevy
      @sufilevy 5 місяців тому

      I'm also very curious! I loved it in F# and tried implementing it in other langs without total success, so it would be cool to see other solutions!

    • @spookyconnolly6072
      @spookyconnolly6072 5 місяців тому +1

      ​@@yash1152, you have to have operators be definable, or have AST macros.
      otherwise i don't think its possible without making a list of callbacks and passing it as some sort of mandatory input to the callbacks (i.e. an explicitly passed continuation)

    • @megaman13able
      @megaman13able 5 місяців тому +2

      Thats why Elixir is da best

  • @arashiryuu1624
    @arashiryuu1624 5 місяців тому +2

    I take issue with the JS part "question-mark operator", the optional chaining operator is specifically `?.` - both characters combined. It is not simply the inclusion of a prefixing question-mark as assuaded to in this video. You cannot optionally chain into bracket-notation by writing `obj?["doSomething"]()` for example, instead you need to fully write out the operator such as `obj?.["doSomething"]()`, another failure point would have been on the function call itself `obj?.doSomething?()` as opposed to `obj?.doSomething?.()` where the latter is valid syntax and would work as expected.

    • @arashiryuu1624
      @arashiryuu1624 5 місяців тому +1

      I feel this is an important distinction to make because we have ternaries which also use the question-mark character, and for anyone who only learned of this operator from this video trying to plug it into their code and wondering why it's not working.

    • @Karifean
      @Karifean 4 місяці тому

      You just taught me that optional chaining into bracket notation and functions is actually possible, thanks.

  • @coder_one
    @coder_one 5 місяців тому +2

    To the second requirement (3:35) - this is obviously a lie. Option is among the algebraic types widely used in functional programming paradigm. However, it in no way specifies its exact implementation, and especially does not require the language to be compiled.
    You can create algebraic types like Option in a dynamic language like JavaScript as well, and they will work exactly as we expect, because Option is a wrapper for a value or no value, not a magic feature offered by language compilers....

  • @Dr.SexySpice
    @Dr.SexySpice 5 місяців тому

    In my opinion JS's handling of null safety with optional-chaining is a band-aid solution. It doesn't require programmers to explicitly think about their types as 'potentially not holding a value' like the nullable-type construct. It allows people to just lazily chain those ?'s until their code stops giving null-refs instead of thinking about how their design should reduce null values as much as possible. One thing missed in this video is how nullable-types in these other languages are exceptional cases for when the programmer consciously wants to allow a type to have "no-value", the default case for everything else is that it simply *cannot* be null, it must have a value upon creation.

  • @Luclecool123
    @Luclecool123 5 місяців тому +5

    Great video! However how isn't Dart mentioned in a null safety video? They did a full rework of the language a few years ago and now is fully null safe with a lot of the features you explained. They have a large number of null aware operators.

  • @CristianMolina
    @CristianMolina 3 місяці тому

    Crystal has nice null checks and union types and it's pretty fast like Go, concurrency is similar, too. Also with a Ruby like sintax❤

  • @sodiboo
    @sodiboo 5 місяців тому

    3:06 This implementation is not only similar, it is identical. All od those macros are just metadata for the compiler to know what versions of rust they are implemented since, except `#[derive]` which implements some additional traits. Other than the lack of trait impls, there is absolutely nothing "naive" about your implementation, and if used with a non-nullable pointer-like type, then it's guaranteed to be one pointer wide. not just the std Option, but also your Optional. The compiler treats them exactly the aame.

  • @ryangrogan6839
    @ryangrogan6839 5 місяців тому +1

    If you could go over Dart null safety, that would be neet. I like it a lot, it implements everything i love in null safety

  • @jnoded
    @jnoded 4 місяці тому +1

    Gosh, I love null safety in Flutter

  • @someonesalt5084
    @someonesalt5084 5 місяців тому +1

    I actually like swift’s language design for the most part, except for a few hiccups that causes some common scenarios to have silly implementations, its limited use case in Apple development (and by extension the stupidity of xcode), and its unfortunate compromise for execution speed.

  • @alexanderhemming6148
    @alexanderhemming6148 4 місяці тому

    that ending was genius for druink people like me that love coding and just kind listen to things like this in aisutations they really shouldn't be. whilst on web based whatsapp waiting for people.
    you should do a video on if ADHD associated with being better or worse for people that code, or if thinking about that distracts from the underlying thing that builds towards enjoyment or proficiency in code

  • @melihcelik9797
    @melihcelik9797 4 місяці тому

    I love these features, they are also implemented in C#. Chaining them on a non-nullable object (such as primitive types like 'int') kinda makes them unreadable because you have to specify a default value for the non-nullable type with '??' operator. Which makes the code more cryptic and less readable for new comers. But its a welcome addition nonetheless

  • @brunodantasm
    @brunodantasm 5 місяців тому +2

    For Python you have the mypy library, which works great with the native type annotations.

  • @GameSmilexD
    @GameSmilexD 4 місяці тому +2

    you can use a linter in a JIT language like python too, just saying, but I also love compilers

  • @oblivious99
    @oblivious99 5 місяців тому +1

    Yeah but the null safety problem was solved years before Haskell, with object oriented systems. Nil can be a real object with real behaviour, that can be extended either at compile time or runtime like any other object. In such systems, the notion of an optional does not exist and is not useful. Once the object tries to interpret a message it can either succeed or fail (usually by redirecting to another message), and there is NEVER absence of value. Chaining operators are ok, as sugar coating for using Nil specifically to emulate absence of value which has a lot of use cases.
    Obviously dynamically typed or untyped systems use this concept (Smalltalk, Ruby, Lisp), but there is also the notable example of the Crystal language, in which values are defined using a union of types. Type unions make inferencing very easy to implement and also include the idea of optionals as a subset out of the box, without needing to deal with generics, a feature that is also excessive in true OOP. Even in an apocalypse scenario where no union types or optionals exist, one can still use the Null Object Pattern to create Null Objects for safeguarding execution from ambiguous datasets.
    Optionals are a mid solution for a problem that mid languages create.

    • @evandrofilipe1526
      @evandrofilipe1526 5 місяців тому +2

      There's no way you just called haskell mid, at least not in that respect. We use Maybe when it suits the model that we're programming

    • @oblivious99
      @oblivious99 5 місяців тому

      @@evandrofilipe1526 I was calling C++ and Java mid, and I meant that `Maybe` was a mid solution in comparison for example to union types. Haskell is indeed a very impressive language which I like. I’m just not sure about optionals in a language where everything could be a valid type, or a valid function.

    • @evandrofilipe1526
      @evandrofilipe1526 5 місяців тому +2

      @@oblivious99 Can you elaborate on how maybe is a mid option? edit: and why union types are better?

    • @perigord6281
      @perigord6281 5 місяців тому +2

      ​@@oblivious99 what value would union types add to Haskell that Sum types don't already solve?

    • @oblivious99
      @oblivious99 5 місяців тому

      @evandrofilipe1526 @perigord6281 First of all I would like to say that my experience in Haskell is limited and there might be some reason why `Maybe` has a specialised importance in a type system where you can have sum types that I don't grasp. As far I understand in languages like Haskell or Idris, `Maybe` should be a subset of sum types, where all potentially absent values are a sum of the desired type (Just desired type) and `Nothing`. But in that case you could simply use sum types to define the value of `Maybe` which I guess is sort of used under the hood (?). Not only that but you could have more powerful optionals, by combining multiple types. I did not suggest that union types are better/worse than sum types which might more or less provide the solution I was talking about in the comment anyway. I am most likely misunderstanding something or am completely wrong, but in any case,
      I was referring instead to how in languages which only contain singular ex-nihilo building blocks like pure object oriented languages one could use Nothing or Nil on Void as actual values of the system with user-programmable behaviour. Defining absence of value then only becomes a natural extension of the system, and handling of this absence is decided by the programmer. Smalltalk-based dynamic languages for example use `nil` as a real object. It is possible to add new messages to `nil` so that it understands just as much as any other object. There is never absence of value in the conventional sense in ex-nihilo systems by definition (unless you are breaking the fourth wall of the virtual machine). There are even automations for handling unknown messages that redirect back to the mother object and dispatch `do not understand` style messages which throw. In crystal lang, you can protect yourself from the billion dollar mistake by having union types of multiple types not just `type` and `Nil`.
      But the important distinction is that instead of disallowing all interaction for this Nil, those languages allow you to modify it, such that under user-defined rules and circumstances, Nil could respond properly. I was talking about this behaviour potentially being superior to simply disabling all functionality on `Nothing`, god forbid there is any imperfection to haskell the language of the gods..

  • @hwstar9416
    @hwstar9416 5 місяців тому +2

    0:47 is that really the most common? I highly doubt it honestly. Accessing memory past its lifetime is what I would think is the most common (such as use after free or dangling pointer).

    • @D0Samp
      @D0Samp 4 місяці тому

      No, those produce garbage data, but at least they're valid memory access as far as the OS and CPU are concerned, since freeing (small amounts of) memory rarely leads to memory pages getting relinquished. The most common invalid address is in fact zero, followed by small positive and sometimes negative integers that result from trying to access a member from a pointer to a structure.

  • @MortvmMM
    @MortvmMM 5 місяців тому +1

    I'm surprised you didn't mention C#, which has a very nice null checking system

    • @agedvagabond
      @agedvagabond 5 місяців тому

      U can still have runtime null reference errors very easily compared to rust though, and it will compile with obvious errors that you see immediately at runtime.

    • @maelstrom57
      @maelstrom57 5 місяців тому

      What's so nice about it?

    • @MortvmMM
      @MortvmMM 5 місяців тому

      @@maelstrom57 stable interface and API, optional chaining, ability to have nullable value types. You can check for nulls using pattern matching ex: if (a is null)

    • @username7763
      @username7763 5 місяців тому

      @@maelstrom57 That it exists at all. C# made the terrible mistake of references being nullable by default. They finally got around to trying to fix that.

    • @Gameplayer55055
      @Gameplayer55055 5 місяців тому

      ​@@agedvagabondall null references will have yellow warning squiggles before compiling the code
      Something must be wrong with your ide, even vs code has that

  • @zakaryakh
    @zakaryakh 5 місяців тому

    Could you make a "Neovim for PHP and Laravel" video?

  • @minneelyyyy8923
    @minneelyyyy8923 5 місяців тому

    no idea how optionals move errors from runtime to compile time? im pretty sure like 90% of my rust panics have been unwrapping a none

  • @AndyIsHereBoi
    @AndyIsHereBoi 5 місяців тому

    this feels like a alternate universe fireship

  • @bity-bite
    @bity-bite 5 місяців тому +7

    I have no idea how you managed to not mention C# in that video.

    • @agedvagabond
      @agedvagabond 5 місяців тому

      C# doesn't really pick up null errors at compile time, I seem to find a way to find a way to cause a null value error every time I run 😂. I have been loving rust coming from c#, I didn't realise how easy low level language actually are.

    • @bity-bite
      @bity-bite 5 місяців тому +1

      @@agedvagabond You don't seem to have NRT enabled in your csproj

    • @agedvagabond
      @agedvagabond 5 місяців тому

      @bity-bite I only taught myself and used c# for a couple of years so never knew that was a thing to be honest. I started using rust now and it's really useful to just be shown exactly where the error is when I compile. I really like c# but there is something really clean about rust code that I am enjoying.

    • @bity-bite
      @bity-bite 5 місяців тому

      @@agedvagabond 👍

  • @cryptic_daemon_
    @cryptic_daemon_ 5 місяців тому

    I been using Rust for high level application, and its just soo conveniente!! Im still not quite sold on its use in Embedded Systems, im still using C, but its just a matter of being readable.

  • @Zeioth
    @Zeioth 5 місяців тому

    My main langs the last 12 years have been [python/js/ts/C#] so it amazes me this is still a problem in 2024.

  • @DanielMircea
    @DanielMircea 5 місяців тому +3

    JS also has undefined, and NaN also isn't doing it any favours.

    • @U20E0
      @U20E0 4 місяці тому

      And "empty item", but NaN exists in every language.

  • @feyroozcode
    @feyroozcode 5 місяців тому +1

    What about Dart languages Null Safety ?

  • @talonhackbarth7652
    @talonhackbarth7652 5 місяців тому +1

    Watching this as a developer using primarily Go and Python. Feeling a little left out, LOL

  • @0xdeadbeef444
    @0xdeadbeef444 4 місяці тому

    Why do languages have the syntax "foo?.bar()", "foo?bar()" seems so much nicer to me

  • @shrootskyi815
    @shrootskyi815 5 місяців тому +1

    > "Although not strictly necessary, I haven't found an [optional type] implementation that doesn't use them [generics]."
    Just thought I'd mention that, technically speaking, Zig's implementation uses the language's incredibly versatile `comptime` feature instead of using generics. In practice, this is largely the same as using generics, but it's cool anyway.

    • @dreamsofcode
      @dreamsofcode  5 місяців тому

      That's very cool. I need to spend some more time with Zig! I'll have to do a video on it!

    • @shrootskyi815
      @shrootskyi815 5 місяців тому

      To clarify, Zig doesn't have generics as a language feature. Either comptime or some form of type erasure must be used when creating "generic" data types or functions.

  • @Serizon_
    @Serizon_ 5 місяців тому

    And i was just learning go , goroutine is just so cool , i like rust as well but its just too deep for me to currently understand

  • @MortvmMM
    @MortvmMM 5 місяців тому +1

    meanwhile Javascript: has 1000 ways to represent null or falsy values

  • @daifee9174
    @daifee9174 4 місяці тому

    Why do you even need optional in C++?
    Most variables are stack allocated, or encapsulate all the heap allocations (vector, unordered_map), references are not nullable and smart pointers do the rest, right?

    • @jakubl8271
      @jakubl8271 4 місяці тому

      "Give me a copy of the biggest value from given vector". What are your proposals to handle empty vector case?

    • @daifee9174
      @daifee9174 4 місяці тому

      @@jakubl8271 you can just check wheter the vector is or isnt empty before running such function, but I understand what you mean

    • @daifee9174
      @daifee9174 4 місяці тому

      @@jakubl8271 (my reply disappeared, so I hope Im not repeating myself) I would check if the vector is empty before running any functions on it, but I do understand what you mean.

  • @terry-
    @terry- 4 місяці тому

    Great!

  • @floppa9415
    @floppa9415 4 місяці тому

    I'm pretty sure the next big thing will be Union Types. If you are using a language that supports it like well (C++' implementation is horrible) like Typescript or F# its brilliant.

  • @krtirtho
    @krtirtho 5 місяців тому +2

    Dart too has null-safety. It is actually the first language to add sound null-safety. And it was before Swift and Kotlin.

  • @raeplaysval
    @raeplaysval 5 місяців тому

    what terminal font do you use?

    • @dreamsofcode
      @dreamsofcode  5 місяців тому

      JetBrainsMono Nerd Font. It's a mouthful!

  • @RandomGeometryDashStuff
    @RandomGeometryDashStuff 5 місяців тому

    00:50 don't forget dereferencing ((void*)-1), that is returned by failed mmap

  • @martijn3151
    @martijn3151 4 місяці тому +1

    Can you let me know where you found the claim that the most common runtime error in C/C++ is segfault? I’m wondering how that’s measured. In professional code segfaults are hardly ever a problem to be honest.

  • @Gameplayer55055
    @Gameplayer55055 5 місяців тому

    I can feel c# was purposely ignored. It has optional types, syntax sugar using? and JavaScript like null coalesce operators .? ?? and ??=

  • @Vendavalez
    @Vendavalez 5 місяців тому +2

    I have complicated feelings about optional values… when the language supports it, it is a pleasure to write code that uses it, but I find it that it becomes very easy to make everything optional which makes it more difficult to figure out issues based on something being null because anything could have been null.
    Whenever a throw together a script in JavaScript for a once and done situation I always start by saying that I will be disciplined about it and I always end up not doing so and then spent a long time chasing unexpected behavior.
    The only reason I have noticed this is because this never happens to me in Go. But I don’t think that I would want to write a one-and-done script in Go.

  • @NatoBoram
    @NatoBoram 4 місяці тому +2

    Weird to not mention Dart

  • @philipmrch8326
    @philipmrch8326 5 місяців тому +10

    Mentions Java but not C# 😢

    • @martinrages
      @martinrages 5 місяців тому +2

      C#'s null handling is so good as well...

    • @dreamsofcode
      @dreamsofcode  5 місяців тому +1

      Forgive me 😭 I had too many C's

    • @philipmrch8326
      @philipmrch8326 5 місяців тому

      @@martinrages It's not as good as Kotlin's, but definitely a huge improvement compared to before it was introduced.

    • @philipmrch8326
      @philipmrch8326 5 місяців тому

      @@dreamsofcode Alright that's okay 😃

  • @erlangparasu6339
    @erlangparasu6339 4 місяці тому +1

    Kotlin, Rust, Swift. You have to mention Dart languange too 💯

  • @seasong7655
    @seasong7655 5 місяців тому

    Wouldn't adding this feature to existing languages give tons of compile errors in existing code? Maybe that's why it wasn't added in python.

    • @perigord6281
      @perigord6281 5 місяців тому

      Not really, adding optionals doesn't make any previous code compile errors. The bigger issue is adoption. Optionals thrive when the ecosystem is designed with them in mind.
      When it isn't, then you have to do both optional checks and null checks.

    • @modernkennnern
      @modernkennnern 5 місяців тому

      C# added "nullable reference types" a few years ago, which added support for `?` for reference types. Previously there were no way to specify that something can be null.
      This was an optional addition, and only a compile-time thing (but can be checked for at runtime if you really need to, but few things do), but it caused/causes a lot of extra development time to transition - definitely worth it however.

  • @nevokrien95
    @nevokrien95 5 місяців тому +1

    I do wan5 more functional stuff in python like a pipe operator.
    As it stands tho the entire ml economy system is stuck with python 3.8 so I would probably not see it.

    • @greyshopleskin2315
      @greyshopleskin2315 5 місяців тому

      Why are you guys still in 3.8?

    • @nevokrien95
      @nevokrien95 5 місяців тому

      @greyshopleskin2315
      Well it's up to 3.11 at times.
      In general because it takes time to move these complicated c packages to the new versions.
      Especially with this new no Gill option that's gota make this whole thing a mess

  • @ex-xg5hh
    @ex-xg5hh 5 місяців тому +1

    A language doesn't have to be compiled to have static checks. In JS, you can use JSDocs with tsc to typecheck your code before running it, while still not having a build step.

  • @Proman4713
    @Proman4713 5 місяців тому +1

    - *Me not understanding a thing because he's using rust and c++*
    - *Me who never tried the optional type before* : wth dude's yappin' on about?!
    - *Him finally mentioning javascript* - me: Yo I fully understand what ur saying bro i swear trust me bro i know what ur on about I swear
    - *Him mentioning optional chaining* - me: I- I'm- I'm hommme 😭

  • @alirezanet
    @alirezanet 5 місяців тому

    About Generics 3:23 Zig has this feature without generics ^^

    • @filipvranesevic8722
      @filipvranesevic8722 5 місяців тому +1

      Zig is capable of generics it just does not call it generics and does not have specific syntax for it, but with comptime and type arguments you are essentially writing generic code

    • @alirezanet
      @alirezanet 5 місяців тому

      @@filipvranesevic8722 well, this is both a correct and wrong statement,
      I agree it is 90 percent like generics, but comptime is happening all in the compile time which in most other languages (maybe except rust) there is some runtime type converter involved.

    • @filipvranesevic8722
      @filipvranesevic8722 5 місяців тому +1

      @@alirezanet in most of the compiled languages (like Rust, C++ and Go) generics work completely in compile time, for each use of generic function in the code, compiler generates separate function with concrete types and during runtime those functions are called as normal

    • @alirezanet
      @alirezanet 5 місяців тому

      hmm interesting 👍I didn't know that

  • @evandrofilipe1526
    @evandrofilipe1526 5 місяців тому +1

    *sniff* Haskell *sob* mentioned 🥲🥲🥲

    • @ProjectExMachina
      @ProjectExMachina 5 місяців тому +1

      My stages of learning Haskell
      This is great!
      WTF?
      Oh, I get it.
      Nope. I don't.
      My head hurts.
      Oh! I see!
      WTF?
      Let's start from scratch.
      Lambda calculus.
      Now it makes more sense.
      Start enjoying WTF moments
      This is great!
      ... Long windy road ahead of me

  • @martoxdlol
    @martoxdlol 5 місяців тому +1

    Dart has good null safety

  • @AsgerJon
    @AsgerJon 4 місяці тому

    In python, use:
    def func(self, *args, **kwargs) -> None:
    self._name = None
    for arg in args:
    if whateverCondition(arg) and self._name is None:
    self._name = arg
    if self._name is None:
    raise TypeError('Couldn't parse, lmao')

  • @bluesquare23
    @bluesquare23 5 місяців тому

    I like to wrap all my references to null in another reference.

  • @nested9301
    @nested9301 5 місяців тому +1

    Dart and c# are not mentioned lol

    • @dreamsofcode
      @dreamsofcode  5 місяців тому

      Both are great languages with null safety!

  • @Mempler
    @Mempler 5 місяців тому +1

    You can "?" OPTIONALS ?!? i only thought its just for results.
    The more yknow!

  • @matthewr8502
    @matthewr8502 5 місяців тому

    Worrying about null safety in a non-type safe language like JS seems like fitting an airbag and then saying this means there is no need to wear a seat belt now.
    I am sure there are cases where it's super useful but I thought the point of dynamic languages was speed of development trumps static analysis catching loads of run-time bugs?

    • @maelstrom57
      @maelstrom57 5 місяців тому

      You must have read that in an article from the 2000s.

  • @user-to2ow2yk8x
    @user-to2ow2yk8x 5 місяців тому +2

    Rust wins the null safety and error handling really simple and robust

  • @Ayymoss
    @Ayymoss 5 місяців тому +10

    C# not getting any light in this video is a crime in itself.

    • @Mempler
      @Mempler 5 місяців тому +2

      bet he isn't using c# as it has a reputation to be basically Windows exclusive (except mono ofc). Which has changed since dotnet core came out thus maybe not knowing that its available for linux and mac.

    • @worgenzwithm14z
      @worgenzwithm14z 5 місяців тому

      Dogwater

    • @AnnasVirtual
      @AnnasVirtual 5 місяців тому +2

      maybe he just hate microsoft lol
      same reason for why typescript isn't shown here

    • @Ayymoss
      @Ayymoss 5 місяців тому +5

      ​@@Mempler Unlikely, I'd imagine anyone in the programming content creator sphere would know that it's now platform agnostic. If not, we probably shouldn't be taking advice from them (not saying this is the case). :D
      Core released in 2016, plenty of time for devs to realise.

    • @007arek
      @007arek 5 місяців тому

      C# is just a clone of java :P,
      It's less popular, so no, it's not a crime.

  • @termisher5676
    @termisher5676 5 місяців тому

    In lua I do
    Value = something or 1

  • @not_a_human_being
    @not_a_human_being 5 місяців тому

    As bad as it sounds - can't we just solve it on the level of exceptions? Perhaps any function that raises an exception would return a "null" if "env=prod" or something. You see?

  • @Finkelfunk
    @Finkelfunk 5 місяців тому

    In C we just put on our sun glasses, spit on our customer and yell "Fuck safety".

  • @cqundefine
    @cqundefine 5 місяців тому

    Honestly, I hate null safety, for me it's really annoying and even in C/C++ segmentation faults aren't that hard to debug. Null safety in some languages like C# feels just really annoying to me. Probably a very uncommon opinion but that's just the way I learned to code.

  • @ragingfred
    @ragingfred 4 місяці тому

    Optionals are just null checks with extra steps

  • @guitaripod
    @guitaripod 5 місяців тому

    Swift and Go FTW

  • @omegahaxors3306
    @omegahaxors3306 5 місяців тому

    I thought that Java was really bad when it came to Null Pointer Exceptions, then here comes C# with its Null Reference Exception, and unlike Java (unless you have the debugger open) good f--ing luck finding out where it came from.

  • @riigel
    @riigel 5 місяців тому +6

    rust ftw 😅

  • @KaiDoesMineCraft10
    @KaiDoesMineCraft10 5 місяців тому

    SWIFT MENTIONED!!

  • @jakubl8271
    @jakubl8271 4 місяці тому

    Calling C++ std::optional a null dereference overcome is a joke. Calling nullopt_optional.value() ends with exception. Calling nullopt_optional-> or *nullopt_optional ends with ub.
    You forgot to check if pointer != nullptr, you gonna forget checking od optional_instance.has_value() as well.