Completely Get Rid of Null Using This Technique

Поділитися
Вставка

КОМЕНТАРІ •

  • @MilanJovanovicTech
    @MilanJovanovicTech  3 місяці тому +1

    Get the source code for this video for FREE → the-dotnet-weekly.ck.page/optional

  • @Andrei-gt7pw
    @Andrei-gt7pw 3 місяці тому +123

    Completely kills the KISS principle. Takes simple code and makes it many times more complicated and difficult to read (which implicitly means more difficult to maintain).
    By same logic you can get rid of bools and make them into an Option. Then refactor every usage of bool in your project.
    There's absolutely nothing wrong with nulls. Just keep checking for nulls where they can occur and you will be fine. Compiler will even tell you where you need to do that.
    Video starts with the premise that null checking on a deeper nested property makes code convoluted. But this 'option monad' thingy makes it ten times more convoluted if you ask me.

    • @user-dc9zo7ek5j
      @user-dc9zo7ek5j 3 місяці тому

      Nulls were a problem in C# few versions ago. By default reference types are nullable, and they did not want to cause user rewrites to fix the syntax and make non-nullable explicit. That is why you see string? which does not make sense, instead of string!. Option type is used in Java for exactly that, to make it explicit that something CAN be null way before the ?. (null coalescing) syntax.

    • @WillEhrendreich
      @WillEhrendreich 3 місяці тому +23

      This does not kill the kiss principle, you're only saying that because you're not used to it, and you haven't seen the benefits for yourself.
      There is absolutely EVERYTHING wrong with nulls, they have no place in any code base.
      They break the type system, completely, you can never tell if that thing is what it says it's going to be if you're letting nulls into your code, especially in older code bases where there is no static analysis for when something could be null. using an option makes it completely clear that a value could not be there, and as such guarantees you must deal with that at any point where this indeterminism could occur.
      does that sound annoying? yeah. but what it does is make you think about how you're reasoning about your types is probably flawed if you're doing this all over the place.
      having Option makes it so you start thinking about making 2 completely separate types where you would have normally just called it good by having null foot guns.
      for instance, say you have a User type, which could be verified or not depending upon whether they have gone through an email verification step, and on this you might have a nullable email because, of course, they don't have that email unless it's been verified, and then you have another property that is a nullable verification date to track how long it's been since that user went through the verifying service, and then a nullable privileges to say what kind of things this user can do, but of course that doesn't apply to ones that haven't been assigned any, so we keep that as null, etc.
      this is a flawed design. it is filled with too much data that is possibly not there, and the amount of null checking that everyone has to do from the moment it's created onwards is absurd, and every place that it isn't checked could be a point where the whole program crashes due to null reference exception.
      it's much better to have a way to compose types together when they could be optional, this forces you to explicitly handle each instance where it could be missing, and you can easily convert one thing to another, or chain operations, or whatever is needed.
      really what you actually want to do is create types without any nulls possible. It's much simpler to create 2 types: an UnverifiedUser and a VerifiedUser, where you can count on each to have the data they're supposed to have, because it should be impossible to create each type if the data isn't there.
      then you can know that you will never have the issue of having to check the UnverifiedUser for permissions, because it's not possible to have one with permissions.
      this leverages the compiler to do the work that a compiler is best at, while getting out of the way of the programmer just trying to implement the business logic without having to have tons and tons of defensive null checking all over the place.
      when you get used to looking at this type of style, it actually becomes way simpler to reason about.
      your complaints of it being "difficult to read" is simply the result of your lack of exposure to it.
      if something does become difficult to do this way, it also highlights how much sneaky complexity was there all along, and should make us rethink the way our types are structured to begin with.
      option monads are a great way to handle things, if there absolutely must be optional values.

    • @Ayalaskin
      @Ayalaskin 3 місяці тому +2

      Also, probably kill performance. In a service which receives milions and milions of requests per day, those things adds up

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

      @@Ayalaskin have you measured this?

    • @Ayalaskin
      @Ayalaskin 3 місяці тому +2

      @@WillEhrendreich Just did it, its around 10% slower and allocates 25% more memory.
      But I ran in the entire original code, if you isolate on the core concept of monad vs nullabe, its probably worse.

  • @paarma1752
    @paarma1752 3 місяці тому +12

    I have used this approach in the past, and it does tend to turn into a mess, as you mentioned. In a real-life application fwihw all the monad handling and generics add a seriously non-trivial overhead to code complexity. Suddenly all the ergonomics that devs are used to are gone and they'll hate it. Eventually some null coalescing will creep in anyway and you'll end up with the worst of the both worlds. Nowadays I happily accept a reasonable chance for easy-to-fix bugs as long as the code stays dead simple and low in abstraction. I rather hotfix simple individual bugs (that our test suite happened to miss) than torture myself and others with bad abstractions and other "previously good ideas" every single day forever. Just my 2 cents...

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

      So what you're saying is, shallow open close as much as possible, and always, always, SRP or die

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

      Let's see if type unoions change anything

  • @jimbob1xghtnm
    @jimbob1xghtnm 3 місяці тому +60

    "The main idea here is to make it explicit that something could either be there or not be there" - Yeah, the nullable type already does that. It is very explicit that the value could "either be there or not be there". The rest of the code is an absolutely unreadable, convoluted mess. The original core was much more readable than your nested Map, Bind, Match, etc. Code is written for other developers to read and your original version was much more readable.

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

      Lol thought the same. It is an unreadable mess.

    • @WillEhrendreich
      @WillEhrendreich 3 місяці тому +12

      readability is more about what you're used to than you think. I find it way more readable this way, I'm used to thinking functionally. I'm not claiming to be better, or something, I'm merely saying that writing this off because of readability concerns is less about it's objective complexity but more that you're not accustomed to it. When you get used to it, it's so much simpler than code filled with a bunch of nasty mutable state and statements. This is way simpler than thinking about the crazy design patterns that OOP has that all become all but meaningless when you have simple functions acting on immutable data, passing everything relevant down to the next part of the pipeline, always having what you need to compose new functionality at all times, because it's never hiding complexity.

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 місяці тому +1

      ... and be able to compose functions on tol of said (possibly) null 'something'

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

      I think the people that say that this is messi code or something like that , are the people that always and time to time want to do the things at the same way. Yes we write code for others to read and for that reason we are not force to write code as a 20 years ago.

    • @kinax2
      @kinax2 3 місяці тому +1

      I totally agree, the original code is much more readable.
      if you are the only one who is working on the project, that's great, but if you are working in team, it can make it more complicated.

  • @Tim61400
    @Tim61400 3 місяці тому +7

    Interesting, but the main drawback, you talked about it, is the fact that not everyone is used to this functionnal way of programming.
    Just one person in the team not being comfortable with it is going to be a problem, but I like this way of getting rid of NULLs

    • @orterves
      @orterves 3 місяці тому +2

      A reasonable argument against it is that it's not a first-class feature in C# (yet) - but in a code base designed to use it, and a team comfortable with it, result monads are worth it

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

      We can educate to overcome that

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

      nulls looks better, imho)

  • @aweklin
    @aweklin 3 місяці тому +25

    This makes the code really complex to read & maintain to junior & some mid-level developers.
    Better to use F# or any other FP if this pattern is heavily needed.

    • @WillEhrendreich
      @WillEhrendreich 3 місяці тому +1

      better to use fsharp anyway, but, assuming you can't/won't, this is a great way to highlight how much complexity your types are hiding by using nullable. better domain modeling of what types are possible to create with what data is needed to begin with, because optional or nullable should be very rare to begin with, they're both more trouble than necessary for most use cases, and if you have to have something, optional is a nicer pattern to work with specifically because it composes so much more clearly and cleanly. it's less complex this way, in actuality, not more, and the "unreadable" argument is really just a matter of lack of being used to it.

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

      How would you convince a C# team to switch to F#? Ain't happening. But you can teach them functional concepts.

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

      +1 moreover, this technique operates with new classes and more memory allocations and overall less effective

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

      @@MilanJovanovicTech I agree with you. It's a good idea to use the FP pettern in C#, in my opinion, not to over complicate it for beginners.
      Also, I think in one of your videos you shared a while back, you mentioned that performance could be a concern because you are always newing up a class (allocated on the heap).
      I like the monard too but, just wouldn't use it too much in performance centric use cases.

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

      @@MilanJovanovicTech I'm not so sure. I think that arguments and evidence can convince rational people to change.
      Is it easy to convince a whole team? No.
      Have I succeeded in wooing my team yet? No.
      But good change takes time, and I've only been a part of this team since march.
      I'm trying to teach functional stuff to people in csharp, and that's difficult in some ways because the old way of doing things holds a colossal amount of weight.
      I have to convince each individual person one on one, address concerns, address style concerns, try to highlight the advantages of doing functional things in an oop -first language without type inference, which is difficult to show how much of an advantage it can be when it's sometimes more code in the short term, or things they're unfamiliar with, or is less ergonomic to accomplish because you have to babysit the compiler, etc.
      I'm simultaneously highlighting all the advantages in developer experience of fsharp.
      As Mads Torgerson, the lead of Csharp says, "try out a full functional language, it's mind blowing".

  • @afouadr
    @afouadr 3 місяці тому +13

    A classic example of callback hell. I strongly suggest investing time in learning OOD instead of doing OOP with some functional craziness.

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

    It feels right in the beginning. But in reality real-word applications are more complex and these functions stack nested, ends up not readable and not debuggable. I personally experienced this. I am not even talking about the knowledge gap of a new team member to catch up with functional way of programming.

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

      FP remains but a distant dream

    • @WillEhrendreich
      @WillEhrendreich 2 місяці тому

      @@ermanafacan there are ways around this. It's kind of the point of the result thing, that it is supposed to kinda flatten this whole thing out. It should be end up in only one level, you make your IO operations as a result, and within the core of things, after matching on the OK, you only work with the inner wrapped type as immutable data, and you only use pure static functions.
      Having a bunch of nested result means that likely the architecture or flow has gotten out of hand, and we can usually solve this by making more composable types that only contain valid data, etc.

  • @smnb6652
    @smnb6652 2 місяці тому +3

    I'm really surprised seeing all the negative comments regarding this.
    It's not hard to implement, it's very readable, and much like Result it makes the code al lot more manageable. I used it before and I like it a lot.

    • @eliashdez
      @eliashdez 2 місяці тому

      I think it brings up negative feelings because it's hard to apply this as a standard in existing codebases or systems. It might work well for newer codebases or for certain programmers, but overall, I agree that it adds some complexity for most users.
      I'm open to finding a better solution that uses some of these ideas but not to an extreme.

    • @MilanJovanovicTech
      @MilanJovanovicTech  2 місяці тому

      Monads are hard, you know?

  • @markovuckovic938
    @markovuckovic938 3 місяці тому +2

    It's strange to see that many people don't this pattern. I do like it and I see many benefits in applying this pattern. The results from .Map() are immutable and that makes them less susceptible to errors and you have a clear fallback logic if the value is null.
    In Java world we use this pattern a lot. Java comes with a build in class called Optional from java.util package that contains similar logic to the one Milan has demonstrated in the video.
    This becomes extremely useful when you need to retrieve a single result (from the database or API call) and apply transformations on in in your business logic.

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 місяці тому +1

      .NET developers are pretty stuck in the OOP box, and struggle to think outside of it. 😁

  • @xBalaDeCanhaox
    @xBalaDeCanhaox 3 місяці тому +2

    Excellent video Milan although I don't see me working with Monad coding style but I could understand it pretty well.

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

    Thks a lo for teaching these functional concepts. I tend to use the result pattern to streamline exception flows. So as this is similar i do not have to much issues reading it, as some say, you need to get used to it. But using it in the null context, as there are already nullavle types and all these ? ?? ! operators simplifing the null checking process, for it's not worth it, especially if colleagues are not used to it. In dart language you have sound null safety, so there can't be null on primitive or reference types, as long as not explicitly saying so. I prefere that concept over options though. but well, it's always good to know different approaches to tackle a problem! keep going! thks again!

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 місяці тому +1

      I think the demonstration was interesting. Whether it's good or bad I leave it up to the viewer.

  • @user-dc9zo7ek5j
    @user-dc9zo7ek5j 3 місяці тому +3

    Default keyword is dangerous when refactoring. I've noticed that when you have a single monad the code is clearer, but when I tried using multiple monads at once it did not. For example, mixing Result with Either. The code in the demo also seems quite unreadable to me with the refactoring, but that is maby because C# has the null coalescing operator. Nullable is also a monad that does the job better than Java's Option (your implementation) but this is because it has compiler support.

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 місяці тому +1

      I always found nullable ref. types kinda weird when I have to do some complex logic around them. Nulls are bad however we look at it.

    • @user-dc9zo7ek5j
      @user-dc9zo7ek5j 3 місяці тому

      @@MilanJovanovicTech Yes, this is because they compromised the language design in favor of backwards compatability. I have mentioned in another comment, they should have actually done the reverse. Explicit non-nullable reference types (class!), and nullable value types (struct?). Of course the confusion would be bigger.

  • @akrotiri3246
    @akrotiri3246 3 місяці тому +2

    this scares developers that never used functional language also
    It is all fun until you want to debug 42 chains of Map().Bind().Match().Filter()...
    just separate them to their own variables with good names it will be much more readable, easy do debug.
    I saw a very old but still in develop project, they had to invent their own EF (yes project is that old), but in some parts if the code they used, in some they did not, they couldn't switch to EF either because this invention was all over they tried to re-write the project as well but failed (well, history tells rewriting is huge project is mostly suicide).

  • @Christopher-iz4bc
    @Christopher-iz4bc 3 місяці тому +2

    Keep it up with the functional content. Yes using match is sometimes more verbose but it actually makes it impossible to have null exceptions if used consistently. It’s unacceptable that a nullable access is just a warning. Honestly if the billable types created only errors and not warnings then they would be much better.
    Also some content on how to actually use LanguageExt would be great. There is hardly any video content out there on when and where to use it.

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

      I think the people who use LanguageExt also probably know how to make it work. Whenever I make a video on monads people go crazy in the comments.

    • @Christopher-iz4bc
      @Christopher-iz4bc 3 місяці тому +1

      @@MilanJovanovicTech The problem is that I think more people would use LanguageExt if more people knew how to use its core features. The higher kinded types and other crazy features are not necessary to use the library but the documentation is overwhelming. Either way super appreciate your videos.
      I think the monad hate is just fear of the unknown.

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

    Great video. I feel like the mistake you made was that your existing code was already pretty declarative with LINQ and nicely separated methods. As a result, the monadic style feels more verbose.
    Instead, you should have had a single 200-line imperative method with 4 different nested for loops, where you have to spend 10 minutes finding which counter variable is which. Not even nullable ref types can save that type of hellscape😭 which is unfortunately common on some "enterprise" codebases. Some "Senior Devs" don't even like LINQ.
    Call me glazing, but I'd rather go through the functional learning curve with Option monads to enforce a safe standard over the former.

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

    Great video of showing the Optional pattern (that Microsoft also uses internally some places).
    But if I don't misunderstand this, the whole video could have ended early with the use of ".OfType()"... it might not be the right in all situations... but if I am right here, it could be a lot cleaner.

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 місяці тому +1

      OfType at which point? It's tough coming up with a good example for these patterns, and also making it something not seen in 100x videos

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

      ​@@MilanJovanovicTech At the about the 3 minutes mark, `.Where(e => e.Result != null).Sum(e => e.Result...)` could be written as `.Select(e => e.Result).OfType().Sum(e => e...)` and the compiler should pick it up without a warning. However, then it's very important to define the correct T in OfType, or make a simple custom extension method that can do this implicit for us.
      Coming up with good examples is a real pain. The example and video is good though.
      For Options vs null, both are good now, but have their own quirks. For NetStandard or Full Framework, Options is mostly the better option.

  • @dangerosa01
    @dangerosa01 3 місяці тому +18

    A lesson about how to complicate easy things

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

      You're not seeing that this is a lesson about how to disambiguate deceptive types and hidden complexity that is already there, but obfuscated by the type system's inconsistencies. don't knock it till you've actually tried it, and implemented things with it, because being able to compose operations together is a big advantage over using NRT.

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 місяці тому +1

      Nah, you must've missed the lesson

  • @antonmartyniuk
    @antonmartyniuk 2 місяці тому

    I like your functional programming videos, despite me being not a fan of functional programming.
    I like nullable types more, for me this way code looks more explicit and readable and I have easier debugging experience

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

    It is interesting but still need to be careful with null at the edge of the system (API client deserialisation and API Endpoints)

    • @WillEhrendreich
      @WillEhrendreich 3 місяці тому +1

      absolutely right, which is why that should be wrapped in a Result monad. you can have a bunch of static pure functions that will always be deterministic and reliable and never have to defensively code in your domain, because you validate only once at the edge of the system, any IO, and then never have to null check again, because if you create your types correctly you will only ever have correct, non null data. composition of pure functions is so much more clear and readable then, you only think about the transformations that need to happen as the data flows through your system.

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

      Of course. This could be interesting for domain modeling.

  • @eliashdez
    @eliashdez 2 місяці тому

    The way I would have it make it simpler is just take care of the data access layer, where we fetch the data we are processing, just return a struct or class that returns default values, instead if nulls. Like, if a collection is non existant, just return an empty collection, it will reduce the null checking almost everywhere. Thanks for the concepts tho.

    • @MilanJovanovicTech
      @MilanJovanovicTech  2 місяці тому

      What if it's not a collection?

    • @eliashdez
      @eliashdez 2 місяці тому

      @@MilanJovanovicTech every type has some default value. I believe this approach would work also across systems, where is not the same code base.

  • @RomanTurovskyy
    @RomanTurovskyy 3 місяці тому +2

    This works well in languages that natively support option types (like Rust) but in C# this technique is an edge case nightmare that shall not be used in real projects. Unless you want to be truly irreplaceable on the project :).

  • @VINAGHOST
    @VINAGHOST 3 місяці тому +6

    i have deja vu, the content is same but somehow it different in some way
    (ok i knew what happen, it was his video about Result while this is about Options)

    • @orterves
      @orterves 3 місяці тому +1

      Monads are worth repeating on, they are very useful

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 місяці тому +1

      Monads everywhere

  • @carlo14
    @carlo14 3 місяці тому +19

    Classic 10x enginner move. Avoids 1 problem now by introducing unnecessary complexity that will bring 10x problems down the road.

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

      spoken like someone who shows they've never written a codebase in a pure functional style. If you do, you get to see what the pits of success feels like, having a pure functional core and Result monads at the IO of the system. I encourage you to step outside of your comfort zone, and to try fsharp for a side project. you will quickly realize that you will love focusing on the business logic instead of constant defensive coding and complicated Gang of four patterns that become irrelevant when the only pattern needed is pure functions and immutable data. don't believe me? please, try it out in earnest, and prove me wrong! you owe it to yourself to test out your assumptions about the way code should be written. perhaps you will find you enjoy it.

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

      Job security, one Option at a time 💪

    • @Christopher-iz4bc
      @Christopher-iz4bc 3 місяці тому +2

      Is it complex or are you just unfamiliar with the concept?

    • @coderider3022
      @coderider3022 2 місяці тому

      lol, lay off it’s my cash cow too.

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

    Are there any coupon codes for your courses especially clean architecture?

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

    interesting prospect for the future, I’ll wait until C# gets full type union support because this syntax is a bit hard to read at times

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

    I wonder if we might be approaching the ROP!

  • @Buutyful
    @Buutyful 3 місяці тому +2

    im into a more functional design myself but i think this optional is more of a religion than anything else, Nullable doesnt represents a valid state but Optional , for some reasons, does...
    I like a result type but a nullable type is already optional enough and i dont need extantions methods on it

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

      If we go down that route, we can call any monad a religion

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

      @@MilanJovanovicTech lol

  • @anton-ivanchenko
    @anton-ivanchenko 3 місяці тому +3

    If you want to write in a functional style, you are better off using F#. When I see code written in C#, I expect it to be primarily an object-oriented language. I understand that some features of a functional language look good in C#, but when people try to make C# a functional language, I don't get it. Why do you need a truncated version of F#? Just use F# to fully support the functional style. For other people, it will also not be a surprise when the main style of the programming language coincides with the style of the written program.

    • @WillEhrendreich
      @WillEhrendreich 3 місяці тому +1

      some of us are unable to make the call to switch to the better language, unfortunately. I would love to have everyone switch to fsharp on my team, but until I can somehow convince the whole department of the developer happiness and ease of use that they are missing out on, I prefer to push functional style, because it still has benefits over oop.

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 місяці тому +1

      The likelihood of getting a team using C# to switch to F# is slim to none. But you can teach them some functional concepts.

    • @anton-ivanchenko
      @anton-ivanchenko 3 місяці тому

      @@WillEhrendreich In teams, the unification of style is still a priority. People can have experience in different programming languages, C++, JavaScript, Prolog, R, etc. Each programming language has its advantages. But it is desirable that the entire program has as similar a style as possible.

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

    It’s interesting but honestly all these makes your code less readable

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

      There's a learning curve here. I can read monadic code pretty easily.

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

    which visual studio theme are you using ?

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

    I have impression that such concepts have meaning if the purpose is to avoid throwing exceptions (monad Result) but monad Option looks less readable and harder to maintain.

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

      Result monad and Option monad solve slightly different problems.

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

    @Milan is this an actual pattern or a really well thought out way of avoiding null and nullables? :-D Either way, I love it! Since nullables were introduced in C#, Swift etc.... I've hated them with a passion!
    Super video by the way, really handy!

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

      Yes, it's a legit pattern for dealing with null - the Option(al) monad

  • @David-id6jw
    @David-id6jw 3 місяці тому

    Bringing this out of the nested comments, but wanted to point out that, for performance purposes (which is a not uncommon concern), the Option class should have been a struct. A quick benchmark puts using the struct version at over 3x the speed of the class version, with no allocation (vs the class version which had about 24 bytes per object).
    Switching to an FP style _looks_ like it should be slow, and when implemented poorly actually _is_ slow, so if you're trying to advocate for it, try not to make the slow version.

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

      Slow is very relative for me. There's 1,000,000,000 bytes in a Gigabyte. Today's CPUs are insanely fast. These micro-optimizations don't concern me as much. I make enterprise applications. If this were software serving millions of requests per second, then I'd reconsider.

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

      Avoiding the allocations (or, to be precise, the garbage collection of them) is far more important than the increased speed.

  • @coderider3022
    @coderider3022 2 місяці тому

    My coding looks like this these days, I still use OOP for the broad strokes/plumbing but at method level, it’s mostly functional. I use a result library to help. You can’t get fixated on 1 single approach. Move with the times.

    • @MilanJovanovicTech
      @MilanJovanovicTech  2 місяці тому

      Are you seeing any drawbacks of this approach?

    • @coderider3022
      @coderider3022 2 місяці тому +1

      @@MilanJovanovicTech unwillingness of others to get involved, requires a good coding level to start. Not many maintained / lightweight packages available so you end up doing a blend of package and own code. My advice would be to follow and study these types of videos and invest in a good book, learning material. I have the Enrico Buonanno. Accept c# isn’t a functional language but you can make your own code much better, don’t be a purist, be patient it takes time to rewire your brain and undo your bad habits and procedural / OO beginnings.

  • @unimatrix20a
    @unimatrix20a 3 місяці тому +1

    Any reason you are not using the CSharp Functional Extension library, which has both a Maybe and Result type and lots of functionality around it?

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 місяці тому +1

      Demoing how to do it from scratch

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

      Implementing patterns yourself helps understanding them better.

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

      @@krccmsitp2884 of course I was just curious if there is anything bad about that library

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

    How about a None or Nil static Field???

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

    Is it possible to just add a boolean flag _isSome to the Option class and get rid of the ValueOption? And then rely on this flag in the appropriate checks.

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

    Yes I know this pattern from very expressive book called functional c# it is great book

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

    Hello Milan. Can you help with starter code so I can follow the video

  • @javadghamari3730
    @javadghamari3730 14 днів тому

    well, I have no mind to use this approch but I may consider it needs masteri of models and entity in the project.

  • @user-pe5qr2wp4u
    @user-pe5qr2wp4u 3 місяці тому

    we need more classes))

  • @robertmrobo8954
    @robertmrobo8954 3 місяці тому +1

    I'll still prefer nulls over this. KISS.

  • @boredyear9017
    @boredyear9017 2 місяці тому

    I feel that there may be some issues when using this for json serialization(?( http)

    • @MilanJovanovicTech
      @MilanJovanovicTech  2 місяці тому +1

      Wrap it in an Option after deserializing - if it can be null

  • @Christopher-iz4bc
    @Christopher-iz4bc 3 місяці тому

    Also, a fully featured functional library is not this verbose because it will have implicit conversions for the types.

  • @LogicException
    @LogicException 3 місяці тому +1

    18:02 And that should be easier to read, understand and maintain? Absolutely not.

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

      Sigh...

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

      If you have never had anything to do with monads before, it may look like this.

  • @ParsaMokhtariHessar
    @ParsaMokhtariHessar 2 місяці тому

    Wow, I feel dump. you lost me at 5:00!

  • @TheScriptPunk
    @TheScriptPunk 3 місяці тому +1

    To add onto what others are saying...
    I used to superengineer these sorts of things...
    And then, I realized, if this is a lib surface unrelated to business logic, im building a helper framework.
    And i made a rule: if it has nothing to do with a specific type or usage of a type, as an extension method, dont makenthat helper framework.
    This seems like it should just ship with the SDK

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 місяці тому +1

      It's not about overengineering. Option is a legitimate pattern. Whether you want to use it all over, or in a few places is up for debate.

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

    Is this a rust tutorial? 😂

  • @soucianceeqdamrashti8175
    @soucianceeqdamrashti8175 2 місяці тому

    All this code just to remove simple null checks? Like many have already posted, keep the code simple, if you are gonna do this, then are you gonna do the same for bool? For other types? Yeah null is a pain, but modern versions of C# and VS Studio already tells us to check for null.

    • @MilanJovanovicTech
      @MilanJovanovicTech  2 місяці тому

      Other types are fine, bool has a meaning (true/false). Null is neither here nor there.

    • @soucianceeqdamrashti8175
      @soucianceeqdamrashti8175 2 місяці тому

      @@MilanJovanovicTech well it is somewhere, its null meaning its nothing, no type yet. I am not saying the solution you provided has not its time and place but i think this is something better addressed in the language than doing it like this.

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

    what is this sorcery ??

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

    Its interesting, but i think it make it harder to understand and teach new members of the team.

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

      Someone may find the idea interesting, good enough for me

  • @Lactorioga
    @Lactorioga 3 місяці тому +1

    Every 2 minutes in video - "and now we get another set of problems"))) Don't you mind that so many sets of problems is a consequences of a bad initial decision to introduce this thing?

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

      Of course there are problems, it's a refactoring video. That's what every major refactor looks like.

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

      With this attitude, science would be a waste of time.

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

    This isn't readable at all.

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

    Yeah, its called "Functional Programming" and has been around for the last 40 years, the people are just too lazy to use it

  • @arekjaski
    @arekjaski 3 місяці тому +2

    Instead of the concept of null and if, we need to "feel" the concept of option monad, bind, map, match. Plus obvious performance downgrades (even with option as a struct). Plus harder do debug. Plus harder to test. Plus much refactor. Plus... no benefit. Functional programming is great. But it is also terrible. Same as OOP. Just take vthe goodies from FP not all things just to be "cool" functional programmer. Find the sweet point between.

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

      "Functional programming is great. But it is also terrible." - that doesn't make a lot of sense

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

      @@MilanJovanovicTech It has, I am just saying that Funcional programming has multiple goodies inside, but also many drawbacks. Same as OOP. Therefore, the best option is to take some parts of FP and some OOP, to make the best composition. You are just going too deep into the FP and being fascinated about it, so You do not see the obvious drawbacks. Its like with LINQ - no OOP programmer complained about it, even it was a FP - and this is a great injection of FP into OOP world.

  • @GuildOfCalamity
    @GuildOfCalamity 2 місяці тому

    I love C#, but C# needs to chill out, there are WAY too many changes being proposed.

  • @JaySHI-h3q
    @JaySHI-h3q 3 місяці тому +1

    It is typical used in Rust!

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

    W T F. how this creepy bunch of lines can be more readable than simple null-checks?
    And then these people complain about the low quality of developers during interviews...
    Also i'm glad to see I'm not the one with this opinion here. Thx guys - I'm not crazy or outdated)
    definitely dislake

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

      Calling some code creepy? Tell me you never did FP without telling me

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

    My lord, it's a fun concept but this should never be used in production really. Its needless complication when null is accepted and standard across almost all OOP these days. Its just codebase poluting for wang waving reasons that i see lots of juniors doing.
    Functional is fine but when its not a first class cirizen in the spec its just noise. I can't see this making it past proposal either really

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

    In Rust language we have it

  • @expertreviews1112
    @expertreviews1112 3 місяці тому +2

    I hate functional programming tbh

    • @user-dc9zo7ek5j
      @user-dc9zo7ek5j 3 місяці тому +1

      Do you really? Or you hate the forcing and inefficient mix of functional paradigms between OOP/Procedural languages which makes this cocktail or confusion? I also do not like that compile time code moves to the runtime, but functional programming paradigms have their ways of solving issues that must be completed as a whole to be effective. In non-functional languages it is best to take the most useful concepts that do not disrupt the OOP flow and apply them. You have Task, Nullable, LINQ that help you build a better software.

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

      have you tried fsharp? you will quickly grow to love how much simpler it is.

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

      Why?

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

      LOL
      What exactly do you think Select and SelectMany actually are?
      What do you think Task actually is?
      Hint: Map, Bind, a Monad.

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

    No null = Rust