You’ll Never Write Functional C# Code if You Don’t Know This

Sdílet
Vložit
  • čas přidán 14. 06. 2024
  • First-class functions, among other things, means you can apply a function to a function to obtain a function. Did you get it?
    C# supports first-class functions, but not always in the most obvious ways. This video will put your understanding of first-class functions to a test. If you can decipher it, you can progress to learn more about functional design in C#. Otherwise, the best course of action is probably to stop and try to understand this critical concept. It is up to you.
    Download source code ► / zoranhorvat
    Join Discord server with topics on C# ► codinghelmet.com/go/discord
    Enroll course Beginning Object-Oriented Programming with C# ► codinghelmet.com/go/beginning...
    Subscribe ► / @zoran-horvat
    ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
    👨 About Me 👨
    Hi, I’m Zoran, I have more than 20 years of experience as a software developer, architect, team lead, and more. I have been programming in C# since its inception in the early 2000s. Since 2017, I have started publishing professional video courses at Pluralsight and Udemy, and by this point, there are over 100 hours of the highest-quality videos you can watch on those platforms. On my CZcams channel, you can find shorter video forms focused on clarifying practical issues in coding, design, and architecture of .NET applications.❤️
    ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
    ⚡️COPYRIGHT NOTICE:
    The Copyright Laws of the United States recognize a “fair use” of copyrighted content. Section 107 of the U.S. Copyright Act states: “Notwithstanding the provisions of sections 106 and 106A, the fair use of a copyrighted work, including such use by reproduction in copies or phono records or by any other means specified by that section, for purposes such as criticism, comment, news reporting, teaching (including multiple copies for classroom use), scholarship, or research, is not an infringement of copyright." This video and our CZcams channel, in general, may contain certain copyrighted works that were not specifically authorized to be used by the copyright holder(s) but which we believe in good faith are protected by federal law and the Fair use doctrine for one or more of the reasons noted above.
    #csharp #dotnet #functionalprogramming
  • Věda a technologie

Komentáře • 53

  • @XXnickles
    @XXnickles Před měsícem +16

    You just showcased one of the main barriers I have had with functional paradigms in c#: the complexity in the signatures. Whether we like it or not, c# is not designed for this, and this is a real pain in the rear end specifically when you work on a team and people have a hard time following (heck, I have tough times myself!) With that said, that trick with the delegate definition is a good one that I am taking note of it. What a shame that currying has to be this complicated (in terms of readability) as it is one of those functional tools that can be very handy in several scenarios to remove a bunch of interfaces and abstract clases. Great explanation!

    • @zoran-horvat
      @zoran-horvat  Před měsícem +4

      C# will hardly advance further in readability, unfortunately.

    •  Před 29 dny

      Viewability and listenability are the future, so don't care.

    • @zoran-horvat
      @zoran-horvat  Před 29 dny

      I like the way you formulated it.

    • @mAcCoLo666
      @mAcCoLo666 Před 13 dny

      I still hope that some future c# versione will introduce dedicated syntax for functions. Even better, that one day c# and f# will become one.

    • @WillEhrendreich
      @WillEhrendreich Před 5 dny

      @@mAcCoLo666 I want fsharp to never be polluted by csharp, lol. it's crazy how much easier all of this is in fsharp. seriously, type inference is the best feature ever.

  • @user-xc8wv5mz5u
    @user-xc8wv5mz5u Před 29 dny +3

    (Native speaker is Chinese, the following is from machine translation)
    Suddenly I realized that using static actually breaks the boundary between object-oriented programming languages and functional programming languages.

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

    You have to admit F# reads a heck of a lot easier than whatever this C# "we must define everything" mess is... 😅

    • @zoran-horvat
      @zoran-horvat  Před měsícem +3

      It is not a mess, but yes, F# syntax is streamlined.

    • @zoran-horvat
      @zoran-horvat  Před měsícem +4

      @Robert-yw5ms Almost always yes, but the implementation of the compiler must change. The type resolution might sometimes need to wait until the time it is used. In the meanwhile, the compiler might go along with rough guesses.
      As a last resort, F# settles down with a guess, such as always assuming some numeric type is int unless proven otherwise.
      I am not the best source for questions regarding the F# compilation process, I must say that, too.

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

      @Robert-yw5ms Hmm, in this case, you'd probably want to define the input types.
      let filter (dataSource: Async) (phrase: string) = async {
      let! bookTypes = dataSource
      return bookTypes |> Seq.filter (fun bookType -> bookType.Title.Contains(phrase, StringComparison.InvariantCultureIgnoreCase))
      }
      The return type would just be deduced, no need to specify it.
      We usually create a function to be able to "map" an Async, so without the computation expression:
      let filter (dataSource: Async) (phrase: string) =
      dataSource
      |> Async.map (Seq.filter (fun bookType -> bookType.Title.Contains(phrase, StringComparison.InvariantCultureIgnoreCase))

  • @Myself0094
    @Myself0094 Před 29 dny +2

    In whole honesty this is exactly where functional C# loses to regular F# and where it becomes obvious it’s not functional first. It sure can be functional enough, but should it?

  • @dusanknezevic9072
    @dusanknezevic9072 Před 29 dny +3

    Well. It's awesome that you can do this.
    Convolutedness of signatures is a bit of a problem.
    All delegate types are incompatible with one another even if they have the same signature (seen as different types by compiler). You can get around this by explicitly typing (wrapping) one. Prime example is that you can't assign Func to Predicate and vice versa.
    It's gonna be interesting to see how C# tackles these incoveniences.
    Functional first languages win here. Like Haskell or F#.

    • @zoran-horvat
      @zoran-horvat  Před 29 dny +1

      Incompatibility of delegates is not an inconvenience - it is intentional. The same situation is with classes. Their objects are not assignable to each other even when the two classes have the same shape.

    • @dusanknezevic9072
      @dusanknezevic9072 Před 27 dny

      @zoran-horvat
      That's more or less ok, depending on point of view. There have been quite interesting discussions with C# team about this, but that's another point
      Unreadability of type signatures is quite a problem. As is currying. It's quite hard to do it in functional way. If I wanted functions to be partially applied that's where type signature unreadability gets problematic.
      Discriminated unions and exhaustive pattern matching would be great additions to C#. But I fear that may drive C# into F# territory with some bad trade-offs in readability and semantics to keep backwards compatibility.

  • @aalasso2
    @aalasso2 Před 2 dny

    > When functional code is done right, most of generics go away
    This statement surprised me! Often, when when I see your FP code, it seems to me that many of the constructs are so general that they would end up being implemented many times over. In the present example, imagine there were many more entity types other than BookType. Would you not make FilterF generic?

    • @zoran-horvat
      @zoran-horvat  Před 2 dny

      The statement is about the other effect. There will be many more generic types, but you will not *see them* due to the var keyword in declarations and generic type inference in calls.

  • @YordanTGeorgiev
    @YordanTGeorgiev Před měsícem +15

    I really try to understand your videos, but for some reason most of them are not clear at all😶

    • @zoran-horvat
      @zoran-horvat  Před měsícem +3

      This particular detail is hard. But once you clarify it, you'll be looking at functions in an entirely new way!

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

      Me too. But I love Zoran’s presentation style and I keep repeating videos until things start to click. I don’t converse like this with my fellow developers so I’m just a bit rusty and Zoran sets an excellent standard to rise to.

    • @d2pgoon86
      @d2pgoon86 Před měsícem +10

      There are a couple reasons for this:
      1. He moves quickly in his demos. I ⏸️ and ⏪ all the time to clarify details that he might gloss over. I prefer this now as I don't need to sit thru mind numbing tedious explanations.
      2. He focuses strictly on the topic, so if something he does is unclear (say with the bare Func signatures), it's mostly on you to figure it out.
      3. He's now skipping over refactorings like Func -> BookFilter etc., because that's now understandably hidden behind Patreon.
      I've come to love Zoran's style as he speaks to you like a young child but does not treat you as one--you must come prepared with knowledge of c#, because he focuses on the abstractions which is where the real learning happens. Just keep watching and it'll click!

    • @1992jamo
      @1992jamo Před 29 dny

      @@d2pgoon86 I think point 3 is the most important. Especially since the delegates hide parameters.

    • @chrisspire
      @chrisspire Před 29 dny

      I am a beginner developer (well, I did that 20 years ago as a hobby in school) and I went through Zoran's tutorials on Udemy to refresh and update my knowledge. They were phenomenal and easy to understand. Most of the stuff here on YT is too advanced for me but I could not find better source of C# knowledge on the internet than Zoran!

  • @okcharles7
    @okcharles7 Před 28 dny +1

    This time, the Turkish Ice cream man flips too long for the C#hildren to take the F#luffy.

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

    as much as i like FP, i worry my juniors wont be able to understand my convoluted delegates

    • @zoran-horvat
      @zoran-horvat  Před měsícem +1

      True, they won't. It takes a lot of experience and even more formal knowledge to start to appreciate functional designs.

    • @zoran-horvat
      @zoran-horvat  Před měsícem +2

      @Robert-yw5ms Currying requires a wider view on functions to understand. A litmus test is for someone to answer why F# functions have no parentheses around arguments.

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

      ​@@zoran-horvat Do i have to know the mathematical background also, to get very good at funktional programming?

    • @zoran-horvat
      @zoran-horvat  Před měsícem +1

      @@UwuseSawase You should have a clear understanding of mappings and functions. That is primarily algebra, rather than mathematical analysis, for example.

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

    So we're using FilterBooks to return a delegate of type Filter which is extended by the static extension method "for", which takes a function that returns Task, and returns a function that has a search string parameter, and then this function is passed to the PromptAndReport method which matches the FilteredDataSource delegate?
    Then finally, it pass it a string to do the filtering? My God.

    • @zoran-horvat
      @zoran-horvat  Před měsícem +1

      That's it :)
      Now, the reason! The reason is that one function knows the data source and another function knows the phrase. Neither should depend on other's data, so the delegate arithmetic comes to the picture. It is the direct inverse of traditional dependency injection in OOP.

    • @1992jamo
      @1992jamo Před 29 dny

      @@zoran-horvat I have to admit Zoran, it took me longer than I care to admit to work out what I was seeing.
      Clearly you are a very talented and experienced developer, but the delegates hide so much that it's extremely hard for me to read without seeing their definitions.
      As always, thanks for the video as I have learned lots. I didn't even realise that functions could be extended.
      It's also very interesting to see how state can be entirely contained within functions.

    • @zoran-horvat
      @zoran-horvat  Před 28 dny

      @@1992jamo I told you it is going to be difficult :)
      But those things you have seen in the end, that is the important lesson. Give it some time, and you will see that it will change the way you look at the functions and delegates, not only in C# but in any language.

  • @LordErnie
    @LordErnie Před 29 dny

    I agree with your description of functional programming. I agree to most of what you do. But there is one slight problem. Functions aren't first class citizens in C# as far as I know. Functions cannot exist on their own. They must exist on a class. A delegate is basically a type description for a function. Its header becomes its type in a sense, because it is. But a description is not a concrete instance. Those must live in the form of methods on objects. Even static methods are just tricks, they are still part of a class. A first class function can live on its own. That means no classes. It can be created, defined, all without a class, or a type, it just exists. Static methods are just a trick (in a sense, they do have use in an OO context these days within C#). Delegates are indeed WAY nicer then only using Func and Action! I agree. Makes it look more like Haskell, where every function needs an abstract type definition (not called that, but we get the idea).

    • @zoran-horvat
      @zoran-horvat  Před 29 dny

      Delegate types exist outside enclosing classes, and they are functions.

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

    mind blown!

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

    Program.cs line 10 is dataSource a great name for the argument?

  • @Rein______
    @Rein______ Před 29 dny +2

    Do this at work just to troll everybody. You dont understand it? Your problem. Lol!

    • @zoran-horvat
      @zoran-horvat  Před 29 dny

      That is what makes it a good joke, I guess.

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

    I'm going to have to watch this a few times. My OO ordered brain resists the truth. :)

    • @1992jamo
      @1992jamo Před 29 dny

      Functional programming can be excellent, but this is unreadable. The delegates hide the structure of the actual functions and when it's this nested it's a nightmare.
      Without putting words in Zoran's mouth, I think that he's showing the power of containing state within expressions rather than classes.
      But going between 5 layers of functions and their abstract representations as delegates seems a bit much to me when we're literally just filtering a collection.

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

    I understood nothing. 😢

    • @zoran-horvat
      @zoran-horvat  Před měsícem +2

      Watch again. This is literally the single point you should understand, and once you do...

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

      @@zoran-horvat There’s many C# features used here that I’m not familiar with. What means “b!”? What do delegates do in this context? Also I constantly lost track of definitions and had to scrub back and forth through the video to get what you were referencing. And the final point of difficulty is not understanding WHY all this indirection would exist. I can do this same function without all these.

    • @zoran-horvat
      @zoran-horvat  Před měsícem

      @@abj136 Can you?

    • @David-id6jw
      @David-id6jw Před 29 dny +1

      @@abj136 The "b!" is easy enough to explain. "!" is the null forgiving operator.
      If you're using nullable reference types, you use "?" to designate that a variable or return type can be null. His Create() functions return things like "BookType?" (this was shown in a recent video he did - Master the Design of Functional Types in C#). So his "a" and "b" variables could potentially be null if the creation logic failed.
      However, since this is a demo, he knows that those are not going to be null, and doesn't want warning squiggles distracting from what he's talking about. So he uses the "!" operator to say, "I definitely know that these are not null, even if the analysis logic says they might be, so don't show me any warnings about them."
      Basically, they're not related to the topic he's trying to explain, just part of the general C# syntax.

  • @ravindranathwi
    @ravindranathwi Před 21 dnem

    Not clear at all maybe you could do better breaking thse down to smaller videos

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

    Great video, really puts into perspective how C# has been evolving over the years. How often do you get to write this type of code in production? Do you find it confuses people that are accustomed to the traditional OOP way of doing things, how do you get over that?
    Pozdrav iz Finsoft/Fincore-a !

    • @zoran-horvat
      @zoran-horvat  Před měsícem

      This is the regular coding pattern when designing pure functional code. It is not common to see this kind of code mixed together with OOP design.