Completely Get Rid of Exceptions Using This Technique

Sdílet
Vložit

Komentáře • 151

  • @MilanJovanovicTech
    @MilanJovanovicTech  Před měsícem +5

    Get the source code for this video for FREE → the-dotnet-weekly.ck.page/rop
    Want to master Clean Architecture? Go here: bit.ly/3PupkOJ
    Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt

  • @antonmartyniuk
    @antonmartyniuk Před měsícem +9

    This is a video made-in-heaven for all the functional programming lovers. Nicely done!

  • @abdushakoor0099
    @abdushakoor0099 Před měsícem +2

    two interesting things i learned from your videos.
    1. Vertical Slice architecture
    2. Railway-oriented programming

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem +1

      Awesome, glad you're finding new ideas 😁

    • @abdushakoor0099
      @abdushakoor0099 Před měsícem

      @@MilanJovanovicTech yes I've been working with Either monad in flutter. Keep up the good work

  • @barrysphone
    @barrysphone Před měsícem +2

    Very interesting video. I use result types with implicit operators for success/error types and use match but had not seen bind or tap before. 👍

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem +2

      So you're probably not doing ROP, but still utilizing Result 👌

    • @barrysphone
      @barrysphone Před měsícem

      @@MilanJovanovicTech yeah, this is the first I've heard of it. I'll have to give it a go. Thanks for the video.

  • @dragannikolic568
    @dragannikolic568 Před měsícem

    Thx for the source code.
    I am doing everything from the scratch and put everything together when possible.
    That way I can check if I did everything right or if I'm missing something.
    Thx. again.

  • @haroldpepete
    @haroldpepete Před měsícem +4

    great video, thanks, can you do a video about the differences between task and valuetask? when use one of them?

  • @eugene5096
    @eugene5096 Před měsícem +5

    I was using it and its a clean and nice way of doing complicated logic. Unfortunetly for most of the team this was not welcomed as considered too complicated. Its so hard to start thinking in functional way these days

    • @paarma1752
      @paarma1752 Před měsícem +1

      I have the same experience. ROP and other functional concepts are actually quite hard. Once dookie hits the fan and your team is under time pressure, devs start cutting corners and finding workarounds. The ROP model that was initially so beautiful and pure suddenly becomes everyone's nightmare full of nasty hacks. Imho this approach just doesn't stand time that well...

    • @gpzim981
      @gpzim981 Před měsícem

      Horrible. Mixing function and OO causes more problem and most of the times devs bringing it to the code base are literally trying to resolve problems that doesn’t exist.

    • @TheScriptPunk
      @TheScriptPunk Před měsícem

      ​@@gpzim981the style it replaced wasn't even oo
      You're mixing that up with general flow of control

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      Skill issue

    • @arunnair7584
      @arunnair7584 Před měsícem

      True. I had faced this problem too. But if I showed them an end-to-end example of this, they usually accepted this approach.

  • @TheScriptPunk
    @TheScriptPunk Před měsícem +1

    My suggestion is to add some sort of container that is passed to each call so the intermediate functions are able to write to that container, such as their error, like failed validation.
    That way, you can couple the error with the call within the same parameter set or something.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      Have a suggestion for the method signature for that?

    • @TheScriptPunk
      @TheScriptPunk Před měsícem +1

      @@MilanJovanovicTech yeah, similar to builder pattern that passes down the object with a this reference, or something along those lines.

    • @arunnair7584
      @arunnair7584 Před měsícem

      If there is any error thrown by any method, processing the rest may not be good in most cases. I implemented a fluent monad years ago that checks if an exception or error has already occurred. If yes, the method does not execute rest of the statements. This is done inside the monad, so the method using this, has to check if the exception flag is turned on, at the end and then fetch the error.

    • @arunnair7584
      @arunnair7584 Před měsícem

      Yes, this is exactly what I used to do.

  • @eugene5096
    @eugene5096 Před měsícem +5

    Milan how you think we can mitigate need to use DI inside extension method, do you think it will be poissble in next c# with new extensions operator ?

    • @TheScriptPunk
      @TheScriptPunk Před měsícem

      What does this mean

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      Just pass it as an argument?

    • @eugene5096
      @eugene5096 Před měsícem

      @@MilanJovanovicTech will it look much uglier if we pass all dependencies as arguments when chaining methods. Imagine you will pass logger in all of them

  • @adambickford8720
    @adambickford8720 Před měsícem +1

    It's nice once you get used to it. Everything is immutable and in your tiny scope, so you don't have to keep as many 'moving parts' in your head. Each 'prefix' gives you an idea of what to expect: `Tap` will be a side effect, `bind` could short circuit, etc.
    It's not like imperative programming where "oh boy, we just set a boolean up above to be consumed down below... maybe".

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem +1

      Definitely there's a learning curve here. Although I didn't find it too difficult. I first worked with RxJs in Angular a while back, before discovering ROP. And it's almost identical.

    • @sushantkhare8467
      @sushantkhare8467 Před měsícem

      @@MilanJovanovicTech exactly, it reminded me of RxJs. I love declarative programming, but it looks like C# wasn't designed for it?

    • @TheScriptPunk
      @TheScriptPunk Před měsícem +1

      @@sushantkhare8467 why are so many people saying c# is not designed for it? Are you talking about the current generation of junior devs not having the cognitive capacity to understand that you don't need a strict approach? Go benchmark it if the structure irks you. This is literally how you set up your host, DI container, chaining linq calls, and don't get me started on generating expression trees.
      This is a common look in many implements of c# programs.
      What you mean is, c# can do this, but nobody does it because they aren't thinking of ways to leverage code.

    • @user-jc6pe2bp1y
      @user-jc6pe2bp1y Před měsícem

      @sushantkhare8476 what do you mean c# wasn’t designed for it? It looks like LINQ lambda notation to me. You know - the syntax that c# introduced

    • @TheScriptPunk
      @TheScriptPunk Před měsícem

      @@user-jc6pe2bp1y they have to have just started a course in programming with morons for professors thats the only way people are coming up with these statements

  • @Naton
    @Naton Před měsícem +8

    I'll do this only if there are no interns in my company. But then again I rather use F#

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem +2

      I think it should be a team-level agreement on if you'd use this. I'm not saying force this down everyone's throat. I find it a very interesting alternative to the "traditional" imperative paradigm.

    • @donarnold8811
      @donarnold8811 Před měsícem +1

      ROP is so much cleaner in F#.

    • @obinnaokafor6252
      @obinnaokafor6252 Před měsícem

      use f# to do what exactly

    • @Andy01010
      @Andy01010 Před měsícem

      Yeah good luck switching to F#… I’d like too see how your management takes it

    • @paarma1752
      @paarma1752 Před měsícem

      There may be interns in your company in the future.

  • @iliyan-kulishev
    @iliyan-kulishev Před měsícem

    I've seen you previous videos on the topic and I love this. And I'm yet to find a convincing argument against it - either at work or in this comment section.
    Here's a question: why you have all these functions on Result as extension methods and not just part of the Result class ?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      I find it more flexible to organize with extension methods. It starts making even more sense with a Result and Result object, which is how I usually do it.
      Most folks against this approach are unfamiliar with FP paradigm, so it feels strange. 😅

    • @TazG2000
      @TazG2000 Před měsícem +1

      The case against it is where the scope of error handling is wider than a single layer and there are several levels of the call stack separating the error from the handler. This pattern is useful, but as with any pattern, trying to fit it into every scenario becomes unwieldy. In general, it isn't worth reinventing the wheel just to "get rid of" alternatives that already fit the purpose.

  • @ugochukwuumerie6378
    @ugochukwuumerie6378 Před měsícem

    Awesome. Is there a way to globally detect and handle result failure in the asp net middleware?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      Yes, you could come up with something. I used to do it with a MediatR pipeline behavior

  • @damianradinoiu4314
    @damianradinoiu4314 Před měsícem

    I would say this pattern is more suitable for algorithm procedure implementations rather than structure. Keeping the OOP paradigm for structural code and FP paradigm for implementations code is my goto approach

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      What would you consider structural code and implementation code?

    • @damianradinoiu4314
      @damianradinoiu4314 Před měsícem

      @@MilanJovanovicTech structural code would be the design of the abstractions interactions themselves (object behaviour patterns) while implementations would be the private state that goes into those abstractions (the procedure themselves). The reasoning behind my idea is because most of the time you want to keep abstractions simple enough in terms of maintainability whereas procedures can grow very complex and this "railroad" approach basically removes the technical complexity from the business one therefore allowing one to focus only on the business logic. Let me know your thoughts as well.

  • @pawel131657
    @pawel131657 Před měsícem

    I'm wandering how this would look if the db and related services functions would have proper async/await implemenations.
    And would need to be awaited before proceeding to next function in the pipeline.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      The function chains would be the same, you'd just have one await at the front, so:
      await ValidateLineItems()
      .Bind(...)
      .TryCatch(...)
      .Tap()
      .Tap()
      .Match();
      The trick is just to create the async overloads for each method, that can accept and return a Task

  • @pedrosilva1437
    @pedrosilva1437 Před měsícem +1

    I personally don't like the Bind, TryCatch, and Tap methods. They complicate code in this ROP. I prefer how LINQ works where you call .Select, .Where, .OrderBy directly... I think that's more readable rather than introducing functions like Bind. Would that be possible in your ROP example?
    But I appreciate the video... It's always good to see new concepts, even if you decide they're not for you. Thanks!

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      Fair enough!

    • @pedrosilva1437
      @pedrosilva1437 Před měsícem

      @@MilanJovanovicTech So do you think there's a way to make your example work more like LINQ? I'm curious if that could be possible, but they always return a list, even if it's empty, and throw exceptions out for failures.

    • @David-id6jw
      @David-id6jw Před měsícem

      @@pedrosilva1437 Well, his custom methods are basically the same thing as LINQ functions, but operating on a different data type. LINQ works on IEnumerables (including things like List, which implements IEnumerable). Milan's functions mostly operate on a single value, his Result type.
      The main difference is in the naming. For example, Select() in LINQ is basically Bind(). It takes one type as input, and generates a (usually) different type as output. There's also Map(), which is what Python uses rather than Select().
      The name "Bind" comes from functional logic, and I always found to be a horrible name for programming purposes. You could, however, simply change the name of the extension method from Bind() to Select(). Since the extension method is bound to the specific designated data type (in this case, Result), it won't conflict with LINQ's version as long as Result never implements IEnumerable.
      There's no equivalent in LINQ to the Tap() function. List itself does actually implement a ForEach() function which is equivalent, but it's not part of the broader LINQ, and isn't an appropriate name for a non-collection type. I would probably rename it Process(), but that's a subjective choice.
      TryCatch() is basically Bind/Select with exception handling. The bind and func function parameters in Bind() and TryCatch() are basically the same thing, except one returns TOut and the other returns Result. You can adjust so that they both use the same signature, and then the entire thing collapses into a single function. I'd merge them together.
      And then Match() just splits the OK and Error results apart to generate the final return value. That's fine as is.

  • @simonklein2335
    @simonklein2335 Před měsícem

    I wonder if that is a production ready code or a well known approach. We are using Hellang Middleware for handling web requests, that way we can return error codes from the Application Layer to the Web layer and then return a formatted error response. To me this looks like a lot of work to put together and the benefits are quite small.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      I wouldn't say this is near production-ready. More showcasing an example.

  • @MyFuzzyAfterlife
    @MyFuzzyAfterlife Před měsícem +4

    I recently joined a team where a pipeline like this was used. The problem was , the whole "old" team had left, so everyone in the team is new. This means that nobody knows what "Bind" or "Tap" means any more, and there is no documentation. This makes this code, very frustrating to maintain. We are in the process of replacing this with simpler "normal" program flow.
    I like the idea of this, but there are big danger flags around it, that makes me avoid it like the plague.

    • @TheScriptPunk
      @TheScriptPunk Před měsícem +2

      The issue is your team doesn't have the competence to be engineers.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem +1

      Well, they're all simple functions. Tap = no side effect. Bind = could fail. Map = like LINQ Select. What made this hard to figure out?

    • @MyFuzzyAfterlife
      @MyFuzzyAfterlife Před měsícem

      @@MilanJovanovicTech I gave those as examples, they are not hard to figure out, but they are not descriptive either. Tap does not tell you what it does. But again, I just used your example, in our case they were equally weirdly named, plus were then highly generic. It makes it difficult to debug, and difficult to parse. People may say it's a bad team, but I would counter that with code should be easy to parse on reading.
      They TryCatch is a great example, I see that method, I know exactly what it does and what it is intended for. I see Tap, I have no clue what that means, do I really have to go delve into the methods to figure out what it does. Yes, your methods are simple, ours were not. Again, I'm not attacking anything that was presented, just my experience with these pipelines.

    • @Eltin123456
      @Eltin123456 Před měsícem +2

      @TheScriptPunk Your opinion suggests a punk that no one would like to work with. Firstly, if the team can handle rewriting such code and then dealing with business tasks, they are competent enough to do their job. Secondly, the code was done in some niche way (in the C# world) and it is proven by many that it is hard to follow (we write code for people, not for our ego). Thirdly, this code does not solve anything.
      I use the functional approach where it solves the problem, so I use 25% functional and 75% OOP. This was using some functional approach just to use a functional approach- not to solve the problem in a much simpler way. The only good thing from this video is that viewers can familiarize themselves with the functional approach, which is not the default way in C#.

    • @TheScriptPunk
      @TheScriptPunk Před měsícem

      @@Eltin123456 sure ok.
      Still has nothing to do with oop

  • @benjsoft
    @benjsoft Před měsícem

    Feels like programming with RxJs in Angular :D

  • @DavidSmith-ef4eh
    @DavidSmith-ef4eh Před měsícem

    cool and all, but you had to write 3 funciton definitons, besides the extension methods. I'll just keep using guard clauses and thorwing. I could get used to it though, if I had to, for example in rust.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      You could also use a NuGet package with these abstractions built in

    • @DavidSmith-ef4eh
      @DavidSmith-ef4eh Před měsícem

      @@MilanJovanovicTech no, I meant the first three functions you wrote besides the extension methods. It's a nice way to program for sure, but it makes it harder readable for most devs (including me). And you also said it's slower because of extra allocations, so.. I am just learning about it to not get left behidn if this trend catches on :D

  • @Rodrick.
    @Rodrick. Před měsícem

    I loved programming like this in Angular with RxJs, but it feels weird in C#, can't explain it better, maybe it's my brain is constantly going "this goes against every uni book you read".
    Would be interesting to see performance metrics for the original method vs ROP. Allocations don't matter as much to me as performance.
    Also would be interesting comparing the same implementation in F#, I could never fully get into it.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      Yes, this is very similar to RxJs so it felt pretty natural to me. There's also Rx.NET 😁

  • @cas818028
    @cas818028 Před měsícem +3

    I understand this completely. But maybe I am just to simple minded this seems like deeply excessive over engineering to solve a very simple problem that is very humans readable that pretty much any c# dev can eyeball in 10 seconds and figure exactly what it’s doing.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      Well, I laid out the pros and cons the way I see them. So everyone can decide what works for them 😁

  • @spreadandexpandknowledge
    @spreadandexpandknowledge Před měsícem

    Great video! Could you cover generic exception handling in the repository pattern in clean architecture without using the Result type? I'm keen to learn how to handle exceptions cleanly in .NET applications. if you have already video then share the link here. Thanks in advance!

  • @user-rx4zz2rt9t
    @user-rx4zz2rt9t Před měsícem

    How do you handle if you need a variable from two previous functions? Say that in the fourth call, you need a value from the second? If you understand what i mean.

  • @ryan-heath
    @ryan-heath Před měsícem +11

    I really dislike this style of programming (in c#)
    Just use a global execration handler that is smart enough to know what to return to the customer.
    Move validation into some global handlers too.
    Just implement your api like a happy path (mostly).
    Yeah I hear you 😅 I am flaming this style in the comments hahaha

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      Do you also dislike LINQ? 😁
      Of course I expected some heat around this topic. As was the case when I previously discussed it. What's your stance on functional programming in C# (in general)?

    • @paarma1752
      @paarma1752 Před měsícem +2

      100% agreed. Being imperative is so much better when your code can branch (e.g. exceptions can happen). You can actually step through it without the control flow bouncing all over the place due to some declarative magic logic and without having to put breakpoints inside callbacks (ugh). I use LINQ all the time, but only if there's no branching, i.e. there are no junctions in my railroad, e.g. when projecting a data structure or when querying with EF.
      Exceptions and occasional result objects ftw!

    • @ryan-heath
      @ryan-heath Před měsícem

      @@MilanJovanovicTech I do like linq a lot.
      I think the main difference with linq is that its domain is well defined.
      That is set oriented selection methods.
      ROP seems to be all over the place. I don’t like to tie everything together into one long fluent syntax.
      Reads fine now, but how about 3 months from now?
      Also it is not immediately obvious where to put or add new functionality opposed to simpler transaction script style.
      FP in c# seems fun at start or in a green field project, but maintainers are going to hate you for it.
      You might even curse your younger self because he wrote some FP code that barely fitted the bill but he went ahead with it anyway because it looked cool. But 3 months from now it looks like a piece of mud … 😅

    • @HenrikElkjrHagen
      @HenrikElkjrHagen Před 24 dny

      This will very quickly lead to highly coupled code, with business logic sprinkled all over the place.

  • @joga_bonito_aro
    @joga_bonito_aro Před měsícem +3

    I prefer the follow errorhandling styles (in order):
    1. Result pattern
    2. obj | err tuple return values (golang style)
    3. exceptions (but I try to avoid it like a cat avoids water)
    The problem with exceptions is that they can happen anywhere down the path and they may, or may not be handled. If you don't handle them, they will explode higher up the call chain and then good friggin luck catching them all like these stupid pokemons. If you use solution 1 or 2, you force yourself handling the error immediately.
    Once you've gone Result pattern, you'll never go back.
    PS: The explanation with the drawbacks in the end was awesome as hell! Much appreciated!

  • @r0bertdenir0
    @r0bertdenir0 Před měsícem

    The problem with using the Result pattern in C# is that the language doesn't give us the syntax to enforce it.
    Historically C# reference types have been "weak" in the sense that a string could be a (string or null).
    That has been fixed with nullable reference types.
    Now a value that could be null must be explicitly defined as being nullable (string?).
    But functions are still "weak" contracts. A function that returns a string can either (return a string OR raise an exception).
    Result doesn't change that.
    A function that returns Result can still (return Result or raise an exception).
    We need some mechanism at the language level where the caller knows that when a function returns Result, there is no possibility of an exception.
    That would be a "strong" contract.
    "async" kind of does this for "Task".
    An async Task function will only raise the exception when it is awaited.
    Unfortunately, a caller can't be confident that a function that returns Task is an async function that won't raise an exception.
    Only the async keyword creates the state machine to wrap the exception, but a function can return Task without using async, which could raise an exception directly.
    Perhaps this might be done with source generators or IL weaving?
    Are there any Result implementations that provide this functionality of "strong" contracts?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      I don't think you will find what you're looking for in the open source world. Best we can do is accept that exception "can" happen, and we can deal with them accordingly.

    • @r0bertdenir0
      @r0bertdenir0 Před měsícem

      ​@@MilanJovanovicTech I do like the Result pattern & think it's a better way to explicitly declare that a function may return a Error, rather than the goto-ish behaviour of Exceptions.
      But currently it feels "ugly" in C#.
      Standard C# functions could (return value OR raise Exception.
      Using Result leads to functions that could ((return T OR Exception) OR raise Exception)
      Is that really an improvement?

    • @r0bertdenir0
      @r0bertdenir0 Před měsícem

      If we follow the principle that functions are opaque, and we only interact with them via the contract of their signature (inputs -> outputs), then we must carry on wrapping everything in try...catch even when we have a functional pipeline, because we don't know if any of those functions in the pipeline will raise an exception instead of wrapping the exception in a Result.

  • @roberteru25
    @roberteru25 Před měsícem

    The Golang way 😂😂😂

  • @copterbuddy
    @copterbuddy Před měsícem

    Interesting

  • @sanampakuwal
    @sanampakuwal Před měsícem +2

    I'd rather implement Result with Service and handle everything in service. looks too complicated for me. coz need to introduce so many functions (btw no need to add custom methods in LINQ, they comes built in)

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem +1

      You can write the functions "in place" also. This was just my way of structuring it to lead into the solution.

    • @TheScriptPunk
      @TheScriptPunk Před měsícem

      Testability in those functions 100% absolute win when working with devs that are lazy. You can go behind and write the tests for them.

  • @thibaultlesuisse8650
    @thibaultlesuisse8650 Před měsícem

    I get it, it looks like functional programming but why use C# instead of F# if you end up doing C# like this?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      Because I can still use C# and the ecosystem I know well

    • @thibaultlesuisse8650
      @thibaultlesuisse8650 Před měsícem

      @@MilanJovanovicTech true! Thanks for the video anyway! Nice to see new styles like this

  • @matswessling6600
    @matswessling6600 Před měsícem +11

    too complicated.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      If you say so

    • @matswessling6600
      @matswessling6600 Před měsícem

      @@MilanJovanovicTech it contsins an embryo to agood idea but I feel that it is too invasive.

    • @icewolf1911
      @icewolf1911 Před měsícem +2

      Ah, not that complicated… it’s like the builder pattern to the next level. It’s fine and looks pretty cool.

    • @matswessling6600
      @matswessling6600 Před měsícem +2

      @@icewolf1911 "its fine and it looks cool". yes I agree its cool and that is what makes it unreadable for most programmers.

    • @icewolf1911
      @icewolf1911 Před měsícem

      @@matswessling6600 Sounds like a skills issue then. That is pretty readable, but I've been doing this for two decades now.

  • @99aabbccddeeff
    @99aabbccddeeff Před měsícem +6

    I would avoid exceptions in some places only if I have to write high performant code or in some cases where it is really needed or more appropriate than throwing an exception. Just avoiding exceptions without any significant reason doesn't make code better at all.

    • @TheScriptPunk
      @TheScriptPunk Před měsícem

      So, you just put "throw" in your code rather than passing data?

    • @another_random_video_channel
      @another_random_video_channel Před měsícem

      totally agreed. Checking result is so 1970. it makes your codebase bloat. There is a reason why .net introduced exception as an alternative. I perfer to use exception for readability then optimise to use result pattern in hot paths

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem +2

      How about avoiding exceptions because you know what the failure is, and you know how to handle it? (If you're thinking that's not exceptional, maybe we're onto something here).

    • @99aabbccddeeff
      @99aabbccddeeff Před měsícem

      ​@@MilanJovanovicTech Right, if I know how to handle some situations in code I won't throw an exception of course. Exceptions is a good tool in right hands and it is only for exception situations. If you take a look at GO lang code, you can see, in some libraries, code turns into if-hell, instead of have one place to handling errors. I don't want to say that we should use exceptions whenever where possible, it is just about they are really helpful and make your code much cleaner, if use them right.
      It's like talking about "goto", many people hate it, but it is also really helpful if it is used right and it is even used in some places in .Net to improve performance, instead of creating additional overhead with flag variables, etc.

  • @arunnair7584
    @arunnair7584 Před měsícem +1

    This is quite an old technique.

  • @giullianosep
    @giullianosep Před měsícem

    I think this is great, but C# is too verbose, it's a lot nicer in F#.

    • @TheScriptPunk
      @TheScriptPunk Před měsícem

      Lemme guess, you're a sr dev that should actually be starting as mid level instead, and don't actually code outside of work because you got your foot in the door?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      I agree that this looks better in F#, since it's a functional language. But I also like to stay in C# for other reasons.

  • @jd-chnl
    @jd-chnl Před měsícem

    it seems you reinvented 'monad'))

  • @TheScriptPunk
    @TheScriptPunk Před měsícem

    Them: I don't like this approach
    You: might be a matter of unfamiliarity
    Them: let me find reasons having nothing to do with the approach to justify unfamiliarity.
    😂
    😂

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem +1

      I've heard these arguments in the past when talking about ROP 😅 So I expected as much. But still, I think it's worth talking about "different" ways to do things. Someone out there might see this, and it could really help them.

  • @gpzim981
    @gpzim981 Před měsícem +2

    Horrible. Mixing function and OO causes more problem and most of the times devs bringing it to the code base are literally trying to resolve problems that doesn’t exist.

    • @TheScriptPunk
      @TheScriptPunk Před měsícem

      Makes your conditionals actually testable

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      Did you ever try this approach in practice and you're speaking from experience?

    • @arunnair7584
      @arunnair7584 Před měsícem

      I have mixed OO with functional, did not face any issues, except in the beginning, but I chalk that upto the learning curve.

    • @TheScriptPunk
      @TheScriptPunk Před měsícem

      @@arunnair7584 you've been using functional the whole time.
      Oo is when you encapsulate data in an object.
      Flow of control, var assignment, property accessing is not oo.

    • @arunnair7584
      @arunnair7584 Před měsícem

      @@TheScriptPunk Nope. I have been using OO since 1999. Functional since around 2018 or so. I avoid getters and setters in OO too.

  • @ilushkinz4424
    @ilushkinz4424 Před měsícem +1

    Please, just stop doing things in C# non idiomatically. The problem with Option/Result monads in C#, is that you just don't have the support from language, to use them without a pain (like in Rust or F#). And the code becames just insanely convoluted.
    If you want to express Option in C#, you can use NRT. If you need to do another way of error handling, just use exceptions.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem +1

      | you just don't have the support from language
      So we add it with some extension methods?

    • @ilushkinz4424
      @ilushkinz4424 Před měsícem +1

      ​@@MilanJovanovicTech that's not the point. The point is that it is not idiomatic and it's not providing that much benefit. You basically need to pattern match every result/option, regardles if you need just to return the failed result and handle happy path (which is like 95%+ of the cases when you're using these monads).
      You also can use panic in go for exception-like error handling. But should you?​

    • @BeauFortLv
      @BeauFortLv Před měsícem

      @@ilushkinz4424 Some confusion here about expected and unexpected exceptions. This approach allows you to handle the expected cleanly using the capabilities that C# currently has. The readability, comes with experience, allows the developers to focus on the business rather than the infrastructure.

  • @rohit704
    @rohit704 Před měsícem

    Have you worked on event sourcing pattern ? I found it most complex pattern.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Před měsícem

      Event sourcing is fundamentally simple. It's the "maintaining an ES system" that's the hard part