Completely Get Rid of Exceptions Using This Technique

  Рет қаралды 19,246

Milan Jovanović

Milan Jovanović

Күн бұрын

Get the source code for this video for FREE → the-dotnet-weekly.ck.page/rop
Join a community of 1000+ .NET developers: / milanjovanovic
Accelerate your Clean Architecture skills: bit.ly/3PupkOJ
Master the Modular Monolith Architecture: bit.ly/3SXlzSt
C# is an object-oriented language with many functional features built in. Functional programming is a fantastic paradigm that I believe every developer should try in their career. In this video, I'll introduce functional programming using the railway-oriented programming approach. ROP allows you to write your program as a series of steps (functions, rails in the railway). Each step can either succeed or fail. ROP will enable you to remove errors from your code in favor of a more expressive approach.
Join my weekly .NET newsletter:
www.milanjovanovic.tech
Read my Blog here:
www.milanjovanovic.tech/blog
Chapters
0:00 What is Railway-Oriented Programming?
3:35 Implementing Railway-Oriented Programming
17:56 Result Pattern drawbacks

Пікірлер: 147
@MilanJovanovicTech
@MilanJovanovicTech 20 күн бұрын
Get the source code for this video for FREE → the-dotnet-weekly.ck.page/rop
@antonmartyniuk
@antonmartyniuk 19 күн бұрын
This is a video made-in-heaven for all the functional programming lovers. Nicely done!
@MilanJovanovicTech
@MilanJovanovicTech 19 күн бұрын
Couldn't agree more!
@abdelrahmandwedar
@abdelrahmandwedar 12 күн бұрын
fr fr
@abdushakoor0099
@abdushakoor0099 8 күн бұрын
two interesting things i learned from your videos. 1. Vertical Slice architecture 2. Railway-oriented programming
@MilanJovanovicTech
@MilanJovanovicTech 7 күн бұрын
Awesome, glad you're finding new ideas 😁
@abdushakoor0099
@abdushakoor0099 7 күн бұрын
@@MilanJovanovicTech yes I've been working with Either monad in flutter. Keep up the good work
@barrysphone
@barrysphone 19 күн бұрын
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 19 күн бұрын
So you're probably not doing ROP, but still utilizing Result 👌
@barrysphone
@barrysphone 19 күн бұрын
@@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 18 күн бұрын
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.
@MilanJovanovicTech
@MilanJovanovicTech 17 күн бұрын
Did you manage to do it?
@dragannikolic568
@dragannikolic568 17 күн бұрын
@@MilanJovanovicTech Yes. Enjoyed it. Became fluent in ROP :)
@haroldpepete
@haroldpepete 20 күн бұрын
great video, thanks, can you do a video about the differences between task and valuetask? when use one of them?
@MilanJovanovicTech
@MilanJovanovicTech 19 күн бұрын
Good idea
@eugene5096
@eugene5096 20 күн бұрын
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 19 күн бұрын
What does this mean
@MilanJovanovicTech
@MilanJovanovicTech 19 күн бұрын
Just pass it as an argument?
@eugene5096
@eugene5096 19 күн бұрын
@@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
@eugene5096
@eugene5096 20 күн бұрын
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 20 күн бұрын
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 20 күн бұрын
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 19 күн бұрын
​@@gpzim981the style it replaced wasn't even oo You're mixing that up with general flow of control
@MilanJovanovicTech
@MilanJovanovicTech 19 күн бұрын
Skill issue
@arunnair7584
@arunnair7584 18 күн бұрын
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 19 күн бұрын
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 19 күн бұрын
Have a suggestion for the method signature for that?
@TheScriptPunk
@TheScriptPunk 19 күн бұрын
@@MilanJovanovicTech yeah, similar to builder pattern that passes down the object with a this reference, or something along those lines.
@arunnair7584
@arunnair7584 18 күн бұрын
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 18 күн бұрын
Yes, this is exactly what I used to do.
@ugochukwuumerie6378
@ugochukwuumerie6378 19 күн бұрын
Awesome. Is there a way to globally detect and handle result failure in the asp net middleware?
@MilanJovanovicTech
@MilanJovanovicTech 19 күн бұрын
Yes, you could come up with something. I used to do it with a MediatR pipeline behavior
@simonklein2335
@simonklein2335 17 күн бұрын
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 17 күн бұрын
I wouldn't say this is near production-ready. More showcasing an example.
@iliyan-kulishev
@iliyan-kulishev 19 күн бұрын
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 18 күн бұрын
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 18 күн бұрын
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.
@pawel131657
@pawel131657 19 күн бұрын
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 19 күн бұрын
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
@damianradinoiu4314
@damianradinoiu4314 10 күн бұрын
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 10 күн бұрын
What would you consider structural code and implementation code?
@damianradinoiu4314
@damianradinoiu4314 10 күн бұрын
@@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.
@Rodrick.
@Rodrick. 18 күн бұрын
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 17 күн бұрын
Yes, this is very similar to RxJs so it felt pretty natural to me. There's also Rx.NET 😁
@pedrosilva1437
@pedrosilva1437 19 күн бұрын
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 19 күн бұрын
Fair enough!
@pedrosilva1437
@pedrosilva1437 19 күн бұрын
@@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 17 күн бұрын
@@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.
@spreadandexpandknowledge
@spreadandexpandknowledge 12 күн бұрын
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!
@MilanJovanovicTech
@MilanJovanovicTech 11 күн бұрын
Great suggestion!
@DavidSmith-ef4eh
@DavidSmith-ef4eh 3 күн бұрын
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 3 күн бұрын
You could also use a NuGet package with these abstractions built in
@DavidSmith-ef4eh
@DavidSmith-ef4eh 3 күн бұрын
@@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
@adambickford8720
@adambickford8720 20 күн бұрын
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 19 күн бұрын
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 19 күн бұрын
@@MilanJovanovicTech exactly, it reminded me of RxJs. I love declarative programming, but it looks like C# wasn't designed for it?
@TheScriptPunk
@TheScriptPunk 19 күн бұрын
@@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 18 күн бұрын
@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 18 күн бұрын
@@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
@benjsoft
@benjsoft 12 күн бұрын
Feels like programming with RxJs in Angular :D
@MilanJovanovicTech
@MilanJovanovicTech 11 күн бұрын
Yeah, quite similar
@user-rx4zz2rt9t
@user-rx4zz2rt9t 16 күн бұрын
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.
@MilanJovanovicTech
@MilanJovanovicTech 16 күн бұрын
Check out the entire ROP playlist, I explained it
@copterbuddy
@copterbuddy 20 күн бұрын
Interesting
@MilanJovanovicTech
@MilanJovanovicTech 19 күн бұрын
If anything
@Naton
@Naton 20 күн бұрын
I'll do this only if there are no interns in my company. But then again I rather use F#
@MilanJovanovicTech
@MilanJovanovicTech 20 күн бұрын
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 20 күн бұрын
ROP is so much cleaner in F#.
@obinnaokafor6252
@obinnaokafor6252 20 күн бұрын
use f# to do what exactly
@Andy01010
@Andy01010 19 күн бұрын
Yeah good luck switching to F#… I’d like too see how your management takes it
@paarma1752
@paarma1752 19 күн бұрын
There may be interns in your company in the future.
@MyFuzzyAfterlife
@MyFuzzyAfterlife 20 күн бұрын
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 19 күн бұрын
The issue is your team doesn't have the competence to be engineers.
@MilanJovanovicTech
@MilanJovanovicTech 19 күн бұрын
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 19 күн бұрын
@@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 19 күн бұрын
@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 19 күн бұрын
@@Eltin123456 sure ok. Still has nothing to do with oop
@cas818028
@cas818028 19 күн бұрын
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 19 күн бұрын
Well, I laid out the pros and cons the way I see them. So everyone can decide what works for them 😁
@rohit704
@rohit704 20 күн бұрын
Have you worked on event sourcing pattern ? I found it most complex pattern.
@MilanJovanovicTech
@MilanJovanovicTech 19 күн бұрын
Event sourcing is fundamentally simple. It's the "maintaining an ES system" that's the hard part
@roberteru25
@roberteru25 18 күн бұрын
The Golang way 😂😂😂
@MilanJovanovicTech
@MilanJovanovicTech 17 күн бұрын
Kinda
@ryan-heath
@ryan-heath 20 күн бұрын
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 20 күн бұрын
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 20 күн бұрын
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 19 күн бұрын
@@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 … 😅
@sanampakuwal
@sanampakuwal 20 күн бұрын
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 19 күн бұрын
You can write the functions "in place" also. This was just my way of structuring it to lead into the solution.
@TheScriptPunk
@TheScriptPunk 19 күн бұрын
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 10 күн бұрын
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 9 күн бұрын
Because I can still use C# and the ecosystem I know well
@thibaultlesuisse8650
@thibaultlesuisse8650 9 күн бұрын
@@MilanJovanovicTech true! Thanks for the video anyway! Nice to see new styles like this
@r0bertdenir0
@r0bertdenir0 6 күн бұрын
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 6 күн бұрын
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 6 күн бұрын
​@@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 6 күн бұрын
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.
@99aabbccddeeff
@99aabbccddeeff 20 күн бұрын
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 19 күн бұрын
So, you just put "throw" in your code rather than passing data?
@another_random_video_channel
@another_random_video_channel 19 күн бұрын
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 19 күн бұрын
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 19 күн бұрын
​@@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.
@satyayuga0
@satyayuga0 20 күн бұрын
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!
@TheScriptPunk
@TheScriptPunk 19 күн бұрын
Golang is trash.
@MilanJovanovicTech
@MilanJovanovicTech 19 күн бұрын
Glad to see some fans of ROP here 😁👌
@arunnair7584
@arunnair7584 19 күн бұрын
This is quite an old technique.
@MilanJovanovicTech
@MilanJovanovicTech 19 күн бұрын
It is
@matswessling6600
@matswessling6600 19 күн бұрын
too complicated.
@MilanJovanovicTech
@MilanJovanovicTech 19 күн бұрын
If you say so
@matswessling6600
@matswessling6600 19 күн бұрын
@@MilanJovanovicTech it contsins an embryo to agood idea but I feel that it is too invasive.
@icewolf1911
@icewolf1911 17 күн бұрын
Ah, not that complicated… it’s like the builder pattern to the next level. It’s fine and looks pretty cool.
@matswessling6600
@matswessling6600 17 күн бұрын
@@icewolf1911 "its fine and it looks cool". yes I agree its cool and that is what makes it unreadable for most programmers.
@icewolf1911
@icewolf1911 16 күн бұрын
@@matswessling6600 Sounds like a skills issue then. That is pretty readable, but I've been doing this for two decades now.
@jd-chnl
@jd-chnl 13 күн бұрын
it seems you reinvented 'monad'))
@MilanJovanovicTech
@MilanJovanovicTech 13 күн бұрын
Not reinvented - this is IT
@giullianosep
@giullianosep 20 күн бұрын
I think this is great, but C# is too verbose, it's a lot nicer in F#.
@TheScriptPunk
@TheScriptPunk 19 күн бұрын
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 19 күн бұрын
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.
@TheScriptPunk
@TheScriptPunk 19 күн бұрын
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 19 күн бұрын
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 20 күн бұрын
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 19 күн бұрын
Makes your conditionals actually testable
@MilanJovanovicTech
@MilanJovanovicTech 19 күн бұрын
Did you ever try this approach in practice and you're speaking from experience?
@arunnair7584
@arunnair7584 18 күн бұрын
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 18 күн бұрын
@@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 18 күн бұрын
@@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 17 күн бұрын
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 17 күн бұрын
| you just don't have the support from language So we add it with some extension methods?
@ilushkinz4424
@ilushkinz4424 17 күн бұрын
​@@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 10 күн бұрын
@@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.
Don't Use Polly in .NET Directly. Use this instead!
14:58
Nick Chapsas
Рет қаралды 49 М.
How to Implement the CQRS Pattern in Clean Architecture (from scratch)
17:36
ИРИНА КАЙРАТОВНА - АЙДАХАР (БЕКА) [MV]
02:51
ГОСТ ENTERTAINMENT
Рет қаралды 9 МЛН
🌊Насколько Глубокий Океан ? #shorts
00:42
Children deceived dad #comedy
00:19
yuzvikii_family
Рет қаралды 8 МЛН
The purest coding style, where bugs are near impossible
10:25
Coderized
Рет қаралды 897 М.
It’s time to move on from Agile Software Development (It's not working)
11:07
`const` was a mistake
31:50
Theo - t3․gg
Рет қаралды 125 М.
Don't throw exceptions in C#. Do this instead
18:13
Nick Chapsas
Рет қаралды 251 М.
What the Heck Are Monads?!
21:08
ArjanCodes
Рет қаралды 69 М.
The 3 Laws of Writing Readable Code
5:28
Kantan Coding
Рет қаралды 327 М.
Master Claims Transformation for Flexible JWT Auth in ASP.NET Core
14:10
Milan Jovanović
Рет қаралды 10 М.
You're not stupid: How to learn difficult things with Obsidian
6:16
Python Programmer
Рет қаралды 325 М.
Blue Mobile 📲 Best For Long Audio Call 📞 💙
0:41
Tech Official
Рет қаралды 1 МЛН
Simple maintenance. #leddisplay #ledscreen #ledwall #ledmodule #ledinstallation
0:19
LED Screen Factory-EagerLED
Рет қаралды 17 МЛН
ИГРОВОВЫЙ НОУТ ASUS ЗА 57 тысяч
25:33
Ремонтяш
Рет қаралды 319 М.
Secret Wireless charger 😱 #shorts
0:28
Mr DegrEE
Рет қаралды 2,5 МЛН
Ультрабюджетная игровая мышь? 💀
1:00