Master the Design of Functional Behavior in C#

แชร์
ฝัง
  • เผยแพร่เมื่อ 23 พ.ย. 2024

ความคิดเห็น • 79

  • @marklord7614
    @marklord7614 5 หลายเดือนก่อน +47

    The real power of learning comes from understanding the application of concepts. This is where Zoran's content truly stands apart. We get to witness how the features of C# work in harmony in a way that not many other content providers demonstrate. And yes, it can be brain-twisting sometimes, but the things worth learning usually are. Take it from me, watch these videos multiple times and play with the concepts and you'll get so much better. I can't praise this content enough.

    • @zoran-horvat
      @zoran-horvat  5 หลายเดือนก่อน +3

      Thanks!

    •  5 หลายเดือนก่อน +1

      You can be brain-twisted, oh! Just imagine the world of juniors coming to be the programmers much faster than old programmers are retired. They use linq but don't understand how and why you can pass a function as an argument to a function.

    • @zoran-horvat
      @zoran-horvat  5 หลายเดือนก่อน +3

      True. Functional programming assumes strong programming skills to begin with. I would never advise a beginner to try to dive into it, as that could lead to numerous misconceptions.

    • @7th_CAV_Trooper
      @7th_CAV_Trooper 5 หลายเดือนก่อน

      @@zoran-horvat I don't know. I think this would have been easier to learn for me in the 1990s before my brain got object orientated.

  • @brianm.9451
    @brianm.9451 5 หลายเดือนก่อน +5

    I’ve been exercising functional paradigms in my work projects. Separating behavior from data allows me to test behavior regardless of data and state changes makes testing predictable. I had to watch this video a few times to drill the concepts in my head!

  • @demarcorr
    @demarcorr 5 หลายเดือนก่อน +15

    "let me twist your brain"
    consider it twisted, but highely intrigued

  • @Menicoification
    @Menicoification 5 หลายเดือนก่อน +7

    Follow up on my comment from some months ago regarding your style of presenting.
    I think you nailed it. For me, you've found the perfect balance with tone variation etc. Very nice to listen to!
    About the contents of your video: Great as always!
    I love it!

    • @zoran-horvat
      @zoran-horvat  5 หลายเดือนก่อน +4

      Thanks! You will probably be happy to know that I am constantly reviewing my processes, from scripting, over recording, to editing, and that is in good part affected by the comments coming from people like you.

    • @Menicoification
      @Menicoification 5 หลายเดือนก่อน +1

      @@zoran-horvat I know ;).. That's why I wanted to follow up on my comment from some time ago. You're doing a very good job!
      I've been developing software for more than 25 years now, but it's always of great value to see how other developers think and incorporate some of their style into ones own.

  • @XXnickles
    @XXnickles 5 หลายเดือนก่อน +2

    It is the most interesting to me that the simple concept of passing functions to a function as parameters (which basically is what the demonstration is about) looks so complicated because of the language syntax. In fact, I got a grasp on the concept by learning a little of F# instead of starting to apply it in C#. The delegate definition trick to high complex function definition is neat, but first you need to really understand the concept of passing function to other functions (high order functions) As always, great explanation!

  • @goldmund67
    @goldmund67 5 หลายเดือนก่อน +2

    Another masterpiece, Zoran. An 'Apply' extension on a delegate... This is pure Zen...

  • @ml_serenity
    @ml_serenity 3 หลายเดือนก่อน +2

    Excellent! Just excellent! You sir deserve much more subscribers considering the quality of the content and educational value.

  • @martinprohn2433
    @martinprohn2433 5 หลายเดือนก่อน +2

    I think one important point of strong typing is is to prevent wrong assignments or wrong casts. Think about types you create to overcome positive obsession. Delegate behaves the same way as other type does. Therefore I don't think that this behavior, that strongly typed delegates cannot implicitly cast to other delegate types, will change in the future.
    I mean your example is a very good example. Think about it, you delegate has a name, a name that describes what the delegate does. Not consider you have a different delegate, with a different name, because it does a different thing. The computer prevents you from accidentally casting the wrong delegates to to the wrong purpose.
    Anyway, using .Invoke is a very good idea. I always used a lambs in this case. Never occurred to me, that I also could use Invoke.

  • @reinhardlackner1925
    @reinhardlackner1925 5 หลายเดือนก่อน +2

    I'm following the dark si..., just kidding, I am following the steady improvements of C# to make functional style programming in C# less verbose and align it more to the functional first langugage F#. From Language.Ext author Paul Louth to "Functional Programming in C# (@Manning)" of Enrico Buonanno to "Functional Programming with C# (@O'Reilly)" from Simon Painter, I am deeply grateful to Zoran for putting out his view on the application of the functional side of C#. I am eager to see where you are taking us.

  • @damianradinoiu4314
    @damianradinoiu4314 5 หลายเดือนก่อน +5

    A masterpiece video!

  • @fifty-plus
    @fifty-plus 5 หลายเดือนก่อน +1

    The power of closures and delegates. Nice one.

  • @WolfieVenturi
    @WolfieVenturi 5 หลายเดือนก่อน +1

    Fantastic video and teaching. Mind is truly bent. Look forward to more!

  • @jwjanse
    @jwjanse 5 หลายเดือนก่อน

    I love your functional C# videos and your clear explanations Zoran; the issue I run into is that - as a freelancer - when I introduce these concepts/code in the projects I work on, it is very hard for colleagues to understand and/or review, let alone maintain it after I have left the project/company. So there is a definite pushback to write more OO-style C#.
    Have you run into this and if so, how did you handle these situations?

    • @zoran-horvat
      @zoran-horvat  5 หลายเดือนก่อน

      That is normal, since C# is an OO-first language. I think the best approach is to mix FP into an OO design. The principal step that every programmer must make is to adopt the immutable mindset. That is also the hardest step to make, so far as I can see.

  • @LE8271
    @LE8271 5 หลายเดือนก่อน +5

    "let me twist your brain". Too late Buddy. That call is way too late. :)

  • @frosky9497
    @frosky9497 5 หลายเดือนก่อน +4

    the only problem i have with functional programming
    is that it is impossible to debug in the larger scale
    going line by line is way more helpfull in that case
    Writing readable and debuggable code should be the goal of all of us

    • @lodevijk
      @lodevijk 3 หลายเดือนก่อน +3

      This is precisely my issue with all of this as well. There is an iceberg and the few nice looking lines on the top are nice. But the rest of the code is extremely difficult to read and understand. If I had a huge legacy codebase and stumbled upon this during debugging, I would ask myself what the f were they thinking.

    • @diadetediotedio6918
      @diadetediotedio6918 หลายเดือนก่อน

      @@lodevijk
      This is just your subjective perspective, it does not hold true because you feel like it.

    • @diadetediotedio6918
      @diadetediotedio6918 หลายเดือนก่อน

      1. You don't understand why or how people do this thing, this is your "problem with functional programming". If you don't understand something you will obviously have a bunch of "problems" with that thing.
      2. It is not "impossible to debug in larger scale" (I'm not even sure what you mean with "large scale" in this context, it is an empty statement), tell me exactly why do you think it is impossible to debug and give me a definition of "larger scale".
      3. FP usually results in bugs and less coupling from the overhall system, so you will need to debug than without it. It is also harder to make bad untangled code (like the messy OOP legacy codebases you see here and there). This is a good tradeof most of the time.

    • @lodevijk
      @lodevijk หลายเดือนก่อน

      @@diadetediotedio6918 I am precisely saying just that: it is my personal issue with it. You are really proving some stereotypes true about programmers who have a total lack of empathy or interpersonal skills. Code is primarily written to be read and maintained, not to be executed. Otherwise we'd be doing assembly.

    • @diadetediotedio6918
      @diadetediotedio6918 หลายเดือนก่อน

      @@lodevijk
      I'm sorry, there is a difference about having troube with something with that thing being objectively hard to grasp.
      And I think there are many misunderstandings in your coment.
      1. That I somewhat "lack" empathy. I have plenty of that "empathy", I just don't find it productive to just consider a random subjective feeling as an argument against a very well and stablished way of programming.
      2. Code is obviously primarily written to be , otherwise , this is literally the truth. Now, this do not mean that we should write code that is hard to read or maintain, this would surely go against our primary goal of executing software as intended (as working with code you don't understand lead to code that will not execute properly).
      3. That because you find something hard, this means that thing is hard on itself. See, my problem with this is that it apply to virtually if you go far enough. Do you think a non programmer can find your well designed OOP code readable? No, that person will scream and want to die if left to maintain it, because you something to be able to that thing. The fact is that you

  • @7th_CAV_Trooper
    @7th_CAV_Trooper 5 หลายเดือนก่อน +1

    What books do you recommend on category theory?

  • @user-tk2jy8xr8b
    @user-tk2jy8xr8b 3 หลายเดือนก่อน

    There is no pattern matching in the yellow box at 2:53. There are a collection expression with a spread element, and a `with`-expression.
    The Map function you have would better be called something else, like Match or Case which are a so-called recursor or an (non-dependent) eliminator, because usually the name Map is reserved in the functional programming context for lifting a function acting on the internals to a function acting on the external preserving the outside type, like the following `Map : (FullNameType -> FullNameType) -> (MononymType -> MononymType) -> (NameType -> NameType)`.
    One can generalize the `Apply` ext function to work with every `Func`. This way it will be universally useful and there will be no need to specify it again and again for each delegate type you want to add partial application to.

    • @zoran-horvat
      @zoran-horvat  3 หลายเดือนก่อน

      @@user-tk2jy8xr8b That actually doesn't work all too well in C#, due to lack of syntactic support.

    • @zoran-horvat
      @zoran-horvat  3 หลายเดือนก่อน

      @@user-tk2jy8xr8b BTW the expression in the yellow box is a pattern matching expression. Don't be too religious about the use of 'match'. Try to see the bigger picture of matching patterns.

    • @user-tk2jy8xr8b
      @user-tk2jy8xr8b 3 หลายเดือนก่อน

      @@zoran-horvat a pattern-matching expression is literally an expression which matches some value to some pattern. In the aforementioned expression, which part is the pattern, which part is the value, and which part is the syntax that matches the value against the pattern?

    • @zoran-horvat
      @zoran-horvat  3 หลายเดือนก่อน

      @@user-tk2jy8xr8b When a chain of ternary expressions are used as a pattern matching expression, then the condition to the left of ? is the pattern and the whole expression evaluated to the right-hand expression. The final expression is evaluated in the catch-all pattern.
      The switch expressions are pattern matching expressions in C# by definition.mYou can transform every switch expression into a chain of ternary expressions. Therefore, the chain of ternary expressions that corresponds to some switch expression is the pattern matching expression by the same definition, too.

    • @user-tk2jy8xr8b
      @user-tk2jy8xr8b 3 หลายเดือนก่อน

      @@zoran-horvat the ternary operator is the recursor on the boolean type. Pattern-matching is a language feature that allows to examine value's structure by matching it to a pattern, i.e. to ask whether the value was constructed in some particular way, in a particular shape, specified by the pattern. `v is true` is a pattern-matching expression (special syntax to reason about the shape of data), `v == true` is not (it's an equality relation), `v ? t : f` is not (it's the recursor). All pattern-matching is eventually transformed into comparisons+conditional jumps (e.g. .NET) or indirect calls (e.g. Haskell) to be performed by the CPU, just as the ternary operator does, that doesn't mean the ternary operator has something to do with pattern matching.

  • @Rein______
    @Rein______ 5 หลายเดือนก่อน +2

    OO (and DDD) has ingrained in me to protect invariants. How to prevent a invalid state transition when the `with` expression can freely do anything?

    • @zoran-horvat
      @zoran-horvat  5 หลายเดือนก่อน

      That is easy. The with expressions cannot "freely do anything". It can only do what the containing function tells it to do.
      Isn't it the same with any mutable object? You can set its private state to whatever you want, but you would never emphasize that as an issue, right?

    • @Rein______
      @Rein______ 5 หลายเดือนก่อน +3

      @@zoran-horvat That thought did cross my mind, but then those mistakes can only be in one place, the class itself.

    • @metallixbrother
      @metallixbrother 5 หลายเดือนก่อน +2

      This was a really interesting video, and certainly a big eye opener. I was trying to do a lot of what is shown here with interfaces, but the delegate approach feels cleaner.

  • @0x4b55
    @0x4b55 5 หลายเดือนก่อน

    We have been told if we want to write performant C# to limit memory allocations as much as possible, reuse objects, and use preallocated memory buffers. On the other hand, in functional programming, objects (records) are thrown at the gabage collector by design. Perhaps .net is not the ideal environment for the function-oriented approach?

    • @zoran-horvat
      @zoran-horvat  5 หลายเดือนก่อน +1

      Garbage collection is a prerequisite for functional programming. I don't know who told you those things and what kind of software you are developing in the first place, but your observations do not apply to general programming. It could be true in games development or in embedded systems, but certainly not in general.

  • @kimfom
    @kimfom หลายเดือนก่อน +1

    I was really coding along and following but you just had to twist my brain 🤣🤣, I am taking a break now to unscramble my brain. See you in 5 mins!

    • @zoran-horvat
      @zoran-horvat  หลายเดือนก่อน +1

      @@kimfom You can't get away with watching this just once.

    • @kimfom
      @kimfom หลายเดือนก่อน +1

      @@zoran-horvat thank you for creating these quality content. Your videos really expands my understanding

  • @mohammedabdalla6452
    @mohammedabdalla6452 5 หลายเดือนก่อน +1

    while i watched the video, there's a part where i was confused is he writing c# code or javascript code
    i think i must read more from now on

  • @HJM9x
    @HJM9x 5 หลายเดือนก่อน

    I want to learn how do fuctional programming in c#. How would you recoment doing this.
    Would you just try in c# or would it be better to learn a functional language and then return to c#.

    • @zoran-horvat
      @zoran-horvat  5 หลายเดือนก่อน

      I would recommend taking F# to learn FP.

  • @Buutyful
    @Buutyful 5 หลายเดือนก่อน

    hi zoran! im missing the point of this demo example here, why dont implement the add unique method inside the book record directly?

    • @zoran-horvat
      @zoran-horvat  5 หลายเดือนก่อน +1

      In functional design, we acknowledge that functions belong to behavior modules that need them. Not all functions defined in one type belong together.
      Therefore, I could test your question with a question: Why would you?

  • @victorchisomnwisu9776
    @victorchisomnwisu9776 5 หลายเดือนก่อน +1

    Awesome video
    could using aliases like below help with avoiding to call the 'Invoke' on the delegate object
    using AuthorWithType = System.Func;

    • @zoran-horvat
      @zoran-horvat  5 หลายเดือนก่อน +6

      That would mean you don't use strongly-typed delegates but only the Func delegates. The downside of that design is that arguments have no name, causing confusion in a complex model.
      Actually, the inability to assign strongly-typed delegates in an uncontrolled manner is a good thing. That adds type safety to functions and lambdas the same way classes add type safety to objects.

    • @BrianHallmanac
      @BrianHallmanac 5 หลายเดือนก่อน

      @@zoran-horvat Follow up question, I'm curious to know if there's a performance difference between a strongly typed delegate vs a Func. My guess is that it won't matter because the compiler will lower the Func to the "same" delegate type.

    • @zoran-horvat
      @zoran-horvat  5 หลายเดือนก่อน +2

      @@BrianHallmanac From what I know, there is no difference. There is, however, a performance penalty if you assign a Func delegate to a strongly typed delegate via a lambda. You should avoid that whenever possible, because the call then consists of two virtual calls instead of just one.
      There is one magnificent improvement there in Rust, where the compiler can sometimes - and quite often - figure that there is just one lambda ending up in a delegate. It then turns that lambda into a statically resolved function, ending the resolution at compile time! I believe .NET will try something similar, if not working on it already.
      I remember a very old paper which concluded that 1/3 of execution time of C++ programs of that time was spent on virtual function resolution. Joggling with virtual calls has always been the curse of OOP, but also its greatest strength.

  • @luc9volts
    @luc9volts 5 หลายเดือนก่อน

    Why a separate static class to create a booktype and not an extension method or a static method in the booktype?

    • @zoran-horvat
      @zoran-horvat  5 หลายเดือนก่อน +1

      That is a common practice - put creation logic in one place, put each batch of behavior into its own place, etc.

    • @luc9volts
      @luc9volts 5 หลายเดือนก่อน

      @@zoran-horvat 👍🏽👍🏽

  • @bloopers2967
    @bloopers2967 3 หลายเดือนก่อน +1

    I have 3 years of experience in coding all C# and I feel like a loser after watching these videos because idk if I'll be able to think like this in future ever. How you guys do it, please advise your junior fellow here

    • @zoran-horvat
      @zoran-horvat  3 หลายเดือนก่อน

      I think every programmer should learn at least one functional language along with learning the basic principles of functional programming. C# is adding more and more syntactic support for functional concepts, but they are of little use (or worse!) if those who use them do not know how to use it effectively.

    • @czbuchi86
      @czbuchi86 3 หลายเดือนก่อน +2

      15 years here ... i sort of understand how, but failing to understand why....

  • @TruptiDaliaTC
    @TruptiDaliaTC 5 หลายเดือนก่อน

    Hello Zoran,
    I try to understand the concepts of Functional Programming via your videos. I often wonder, the model you use have only 2 properties. In reality a model would have several properties. If a model has 10+ properties, would working like this for each property be a good idea ?? What do you think ?

    • @zoran-horvat
      @zoran-horvat  5 หลายเดือนก่อน +1

      Actually, such models are frequent in object-oriented design, but not in functional. In functional design, we tend to group related concepts and represent them together, so a top-level type would consist of a few contained types, each consisting of a few other types, and so on. It is a true rarity to encounter a large type definition in a functional domain model.

    • @TruptiDaliaTC
      @TruptiDaliaTC 5 หลายเดือนก่อน

      @@zoran-horvat thanks for your prompt response. This clears to some extent. So, in OO design, for objects with fewer properties, we can implement functional design and use in other models? I am trying to implement small parts of Functional code in my OO code, but I find it difficult due to these concerns and give up.

  • @belongstomyself
    @belongstomyself 5 หลายเดือนก่อน +3

    Complicated yet interesting

    • @zoran-horvat
      @zoran-horvat  5 หลายเดือนก่อน +3

      Functional design has a steep learning curve, but eventually takes you further up than object-oriented design. The end result is very powerful.

    • @pl4gueis
      @pl4gueis 5 หลายเดือนก่อน +1

      @@zoran-horvat OO also has a steep learning curve with all the rules, anti patterns you have to be aware of. So I wouldn't say its complicated. Its just a different way of thinking. If universities would also teach functional concepts people would have an easier time adjusting.

  • @1Eagler
    @1Eagler 5 หลายเดือนก่อน

    After lisp,xslt now i have to learn f.p. in c#?
    O tempora o mores.

  • @thomaseyde275
    @thomaseyde275 5 หลายเดือนก่อน

    I can easily find all implementations of an interface, then identify an offending implementation. Not so easy with delegates. How to fix that?

    • @zoran-horvat
      @zoran-horvat  5 หลายเดือนก่อน

      I am not sure what you mean. The compiler reports assignment errors to delegates the same way as with anything else in your code.

  • @Alguem387
    @Alguem387 5 หลายเดือนก่อน

    Partial aplication is equivalent to depency injection

    • @zoran-horvat
      @zoran-horvat  5 หลายเดือนก่อน

      Partial application of other functions is equivalent to dependency injection. Partial application of values is equivalent to creating a stateful object.

  • @kimfom
    @kimfom หลายเดือนก่อน +1

    Ohh my poor OOP brain has been destroyed

  • @ryanrobbins3846
    @ryanrobbins3846 5 หลายเดือนก่อน +1

    🔥 🤯

  • @7th_CAV_Trooper
    @7th_CAV_Trooper 5 หลายเดือนก่อน

    In the 1700's you'd get burned for witchcraft coding with this black magic. I have to watch every functional video 3 or 4 times.