This is perhaps the greatest feature of modern programming languages.

Поділитися
Вставка
  • Опубліковано 24 гру 2024

КОМЕНТАРІ • 409

  • @IgorStojkovic
    @IgorStojkovic 11 місяців тому +140

    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 11 місяців тому +17

      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 11 місяців тому +32

      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 11 місяців тому +23

      ​@@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 11 місяців тому +8

      ​@@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 11 місяців тому +17

      ​@@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 11 місяців тому +182

    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 11 місяців тому +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 11 місяців тому +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 11 місяців тому +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 11 місяців тому

      @@cleavesolais Thanks for your answer.

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

      Nothing will save you from stupid.

  • @Christian-op1ss
    @Christian-op1ss 11 місяців тому +286

    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 11 місяців тому +11

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

    • @Christian-op1ss
      @Christian-op1ss 11 місяців тому +12

      @@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 11 місяців тому +66

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

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

      no, swift does it better

    • @Soromeister
      @Soromeister 11 місяців тому +24

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

  • @joopie46614
    @joopie46614 11 місяців тому +15

    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 6 місяців тому

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

  • @k6l2t
    @k6l2t 11 місяців тому +4

    I completely disagree with the premise of this entire video. Null dereferences are not an issue at all, and in fact I pray to the computer gods that when a crash dump rolls in that the error is a simple null dereference. They are typically extremely easy to debug with a simple stack trace. The worst bugs are the ones who corrupt memory catastrophically, or the bugs where things _appear_ to run correctly to everyone, but are actually extremely buggy scenarios such as a memory leak, where the program can fail in production environments at random points in the future for random customers. As far as I can tell, there are no good solutions to memory leaks and the like in modern languages.

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

    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.

  • @LarryGarfieldCrell
    @LarryGarfieldCrell 11 місяців тому +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 11 місяців тому

      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.

  • @MonochromeWench
    @MonochromeWench 11 місяців тому +29

    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 11 місяців тому +3

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

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

      ​@@etherweb6796VSCode is written in Typescript

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

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

    • @etherweb6796
      @etherweb6796 11 місяців тому +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 11 місяців тому

      @@etherweb6796 gl with your 'career'

  • @TAP7a
    @TAP7a 11 місяців тому +16

    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

  • @xcoder1122
    @xcoder1122 11 місяців тому +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.

  • @martoxdlol
    @martoxdlol 11 місяців тому +3

    Dart has good null safety

  • @marekful
    @marekful 11 місяців тому +28

    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 11 місяців тому +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 11 місяців тому +9

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

  • @TheIppoippo
    @TheIppoippo 11 місяців тому +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.

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

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

  • @itzkxhu
    @itzkxhu 11 місяців тому +43

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

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

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

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

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

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

      If only libraries could actually take advantage of it

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

      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 11 місяців тому +3

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

  • @henryfleischer404
    @henryfleischer404 11 місяців тому +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.

  • @adamszalkowski8226
    @adamszalkowski8226 11 місяців тому +99

    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 11 місяців тому +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 11 місяців тому +11

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

    • @dreamsofcode
      @dreamsofcode  11 місяців тому +34

      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 11 місяців тому +2

      ​@@ttuurrttlleIt won't happen

    • @OldKing11100
      @OldKing11100 11 місяців тому +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.

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

    PHP also added null safety in recent years

  • @coder_one
    @coder_one 11 місяців тому +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....

  • @khangle6872
    @khangle6872 11 місяців тому +4

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

  • @feyroozcode
    @feyroozcode 11 місяців тому +2

    What about Dart languages Null Safety ?

  • @milasudril
    @milasudril 11 місяців тому +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.

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

      @@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 11 місяців тому

      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 11 місяців тому

      @@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 10 місяців тому

      @@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.

  • @gyuyoungpark5509
    @gyuyoungpark5509 11 місяців тому +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.

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

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

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

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

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

      @@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

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

    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.

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

    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

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

    Weird to not mention Dart

  • @darrennew8211
    @darrennew8211 11 місяців тому

    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.

  • @giorgiobarchiesi5003
    @giorgiobarchiesi5003 11 місяців тому +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 11 місяців тому

      i dont like him.

    • @giorgiobarchiesi5003
      @giorgiobarchiesi5003 11 місяців тому +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.

  • @TheHeavenlyDemonSupreme
    @TheHeavenlyDemonSupreme 11 місяців тому +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.

    • @TheHeavenlyDemonSupreme
      @TheHeavenlyDemonSupreme 11 місяців тому +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 11 місяців тому

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

  • @hwstar9416
    @hwstar9416 11 місяців тому +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 11 місяців тому

      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.

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

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

  • @dacomputernerd4096
    @dacomputernerd4096 11 місяців тому +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

  • @bity-bite
    @bity-bite 11 місяців тому +8

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

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

      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 11 місяців тому +1

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

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

      @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 11 місяців тому

      @@agedvagabond 👍

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

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

  • @martijn3151
    @martijn3151 11 місяців тому +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.

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

    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.

  • @shrootskyi815
    @shrootskyi815 11 місяців тому +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  11 місяців тому

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

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

      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.

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

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

    • @chri-k
      @chri-k 11 місяців тому

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

  • @oblivious99
    @oblivious99 11 місяців тому +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 11 місяців тому +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 11 місяців тому

      @@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 11 місяців тому +2

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

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

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

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

      @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..

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

    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

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

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

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

    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.

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

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

  • @Damian-rp2iv
    @Damian-rp2iv 11 місяців тому

    Nobody will ever read that but Java's Optional is NOT a way to handle null type. It's only meant to more conveniently handle nullable value in functional programming like code.
    The correct way to handle null type in Java is through Type Annotations

  • @KaiDoesMineCraft10
    @KaiDoesMineCraft10 11 місяців тому +10

    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  11 місяців тому +3

      The defer keyword is really awesome as well

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

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

  • @daifee9174
    @daifee9174 10 місяців тому

    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 10 місяців тому

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

    • @daifee9174
      @daifee9174 10 місяців тому

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

    • @daifee9174
      @daifee9174 10 місяців тому

      @@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.

  • @Proman4713
    @Proman4713 11 місяців тому +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 😭

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

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

  • @obuqwe
    @obuqwe 11 місяців тому +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 ^^;)

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

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

  • @spookyconnolly6072
    @spookyconnolly6072 11 місяців тому +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 11 місяців тому +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 11 місяців тому

      @@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.

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

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

  • @AsgerJon
    @AsgerJon 11 місяців тому

    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')

  • @melihcelik9797
    @melihcelik9797 11 місяців тому

    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

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

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

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

      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 11 місяців тому

      What's so nice about it?

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

      @@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 11 місяців тому

      @@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 11 місяців тому

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

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

    Gosh, I love null safety in Flutter

  • @niko-pp
    @niko-pp 11 місяців тому +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 11 місяців тому +1

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

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

      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 11 місяців тому +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 11 місяців тому +2

      Thats why Elixir is da best

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

    Mentions Java but not C# 😢

    • @martinrages
      @martinrages 11 місяців тому +3

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

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

      Forgive me 😭 I had too many C's

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

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

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

      @@dreamsofcode Alright that's okay 😃

  • @minneelyyyy
    @minneelyyyy 11 місяців тому

    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

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

    Dart and c# are not mentioned lol

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

      Both are great languages with null safety!

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

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

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

    FINALLY something comprehensive on the topic! Thanks!

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

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

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

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

    • @filipvranesevic8722
      @filipvranesevic8722 11 місяців тому +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 11 місяців тому

      @@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 11 місяців тому +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 11 місяців тому

      hmm interesting 👍I didn't know that

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

    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?

  • @someonesalt5084
    @someonesalt5084 11 місяців тому +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.

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

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

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

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

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

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

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

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

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

    this feels like a alternate universe fireship

  • @mahangholizadeh
    @mahangholizadeh 11 місяців тому +2

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

  • @nathangreene3
    @nathangreene3 11 місяців тому +1

    If you're just going to provide a default value every single time a null value is detected, why make the thing nullable? This is easily handled for primitives, but for objects that implement an interface, this requires manually checking for nil, then handling each case accordingly. Usually, there is no default value provided and functions just return an error or panic. In my opinion, this is as it should be.

    • @AndreiGeorgescu-j9p
      @AndreiGeorgescu-j9p 11 місяців тому

      Shouldn't be returning errors

    • @nathangreene3
      @nathangreene3 11 місяців тому

      @@AndreiGeorgescu-j9p Solid insight right there.

    • @richardblain4783
      @richardblain4783 11 місяців тому

      You can specify a different default value with each reference to the optional value, instead of one default value determined when the optional value is set.

    • @AndreiGeorgescu-j9p
      @AndreiGeorgescu-j9p 11 місяців тому

      @@nathangreene3 the insight is that partial functions need to be made total but you're a soydev who thinks random exceptions are a good idea so I don't think elaborating is going to do much for you

    • @nathangreene3
      @nathangreene3 11 місяців тому

      @@AndreiGeorgescu-j9p I didn't say to throw exceptions. I should have said I work with Go primarily so errors and exceptions are very different things to me.

  • @Verrisin
    @Verrisin 11 місяців тому +1

    MODERN ? dude .... T-T - It was in sensible languages from a long time ago... People just finally adopted it into languages they use primarily ... which are awful anyway, but it's nice they are bringing in features from languages designed by people with brain, and not just made to be as similar to existing and as usable by as dumb developers as possible...

    • @Verrisin
      @Verrisin 11 місяців тому +1

      and it's not just Haskell, it's any ML, etc...

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

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

    • @Mempler
      @Mempler 11 місяців тому +3

      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.

    • @anarchymatt
      @anarchymatt 11 місяців тому

      Dogwater

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

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

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

      ​@@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 11 місяців тому

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

  • @floppa9415
    @floppa9415 11 місяців тому

    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.

  • @Vendavalez
    @Vendavalez 11 місяців тому +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.

  • @ex-xg5hh
    @ex-xg5hh 11 місяців тому +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.

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

    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 11 місяців тому

      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 11 місяців тому

      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.

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

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

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

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

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

    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!

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

    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 11 місяців тому

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

  • @jakubl8271
    @jakubl8271 10 місяців тому

    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.

  • @CristianMolina
    @CristianMolina 10 місяців тому

    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❤

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

    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.

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

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

  • @ES-eb6pb
    @ES-eb6pb 11 місяців тому +1

    i have 0 respect to any language that has no null safety

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

    what terminal font do you use?

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

      JetBrainsMono Nerd Font. It's a mouthful!

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

    *sniff* Haskell *sob* mentioned 🥲🥲🥲

    • @ProjectExMachina
      @ProjectExMachina 11 місяців тому +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

  • @ragingfred
    @ragingfred 11 місяців тому

    Optionals are just null checks with extra steps

  • @alexanderhemming6148
    @alexanderhemming6148 11 місяців тому

    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

  • @nevokrien95
    @nevokrien95 11 місяців тому +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 11 місяців тому

      Why are you guys still in 3.8?

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

      @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

  • @j.r.r.tolkien8724
    @j.r.r.tolkien8724 11 місяців тому

    "blah blah bla... is actually a monad."
    Oh! That explains a lot. I'm pretty sure 99% of the viewers know what a monad is.

  • @ejonesss
    @ejonesss 11 місяців тому

    could someone write a patch to fix a specific copy of python to be safe?
    each time a new version comes out they would have to reverse engineer and patch it just like doing a [k] patch for software piracy.
    probably why it is being differed is because the creators of python are lazy and dont feel like adding a safety check.

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

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

  • @omegahaxors9-11
    @omegahaxors9-11 11 місяців тому

    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.

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

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

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

    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