Become a sponsor to access source code ► https://www.patreon.com/posts/source-code-17-c-95476297
Join Discord server with topics on C# ► https://codinghelmet.com/go/discord
Enroll course *Beginning Object-Oriented Programming with C#* ► https://codinghelmet.com/go/beginning-oop-with-csharp
The syntax of the C# programming language is changing. It has been changing since version 1, and we are still witnessing the addition of more details to it. Have you ever considered why we are getting these pieces of syntax and not some other?
In this video, we will revisit a number of seemingly minor improvements added to the language over the years and draw them to a conclusion: Novel C# syntax makes writing pure functions easy.
It takes time to accept pure functions as a design tool and a lot of practice to make the most out of them. But one thing I promise to you: Once you get there, you will never look back to the old-school imperative coding.
And more: Your code will be way shorter than it used to be. How much shorter? 50-70% on average. That should motivate every programmer to start using the novel C# syntax as intended.
⚡️Chapters:
⌚ 00:00 Intro
⌚ 00:53 Imperative code (100% length)
⌚ 03:17 Object-oriented code (57% length)
⌚ 05:35 Comparing different styles
⌚ 06:45 Functional code (50% length)
⌚ 09:17 Pure functions (40% length)
⌚ 11:58 Conclusion
Thank you so much for watching! Please like, comment & share this video as it helps me a ton!! Don't forget to subscribe to my channel for more amazing videos and make sure to hit the bell icon to never miss any updates.🔥❤️
✅🔔 Become a patron ► https://www.patreon.com/ZoranHorvat
✅🔔 Subscribe ► https://www.youtube.com/channel/UCxsWfh8LCcn55mFB6zGBT1g?sub_confirmation=1
⭐ Learn more from video courses:
Beginning Object-oriented Programming with C# ► https://codinghelmet.com/go/beginning-oop-with-csharp
⭐ Collections and Generics in C# ► https://codinghelmet.com/go/collections-and-generics-in-cs
⭐ Making Your C# Code More Object-oriented ► https://codinghelmet.com/go/making-your-cs-code-more-oo
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
⚡️ Have a look at our other Videos :
👉 Using GitHub Copilot to Write Complex Code | Step-by-step Tutorial ► https://youtu.be/XktMg5jnaBI
👉 Coding with GitHub Copilot - Beginner to Master | VS Code Demo ► https://youtu.be/B9DKv09IfT4
👉 What is Covariance and Contravariance in C# ► https://youtu.be/Wp5iYQqHspg
How to Initialize a Clean ASP.NET Core Project with Entity Framework Core and Identity ► https://youtu.be/3NGz1G_HF94
👉 The Null Conundrum: A Guide to Optional Objects in C# ► https://youtu.be/8-2xr_kBRnQ
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
⭐ CONNECT WITH ME 📱👨
🌐Become a patron ► https://www.patreon.com/ZoranHorvat
🌐Buy me a Coffee ► https://ko-fi.com/zoranhorvat
🗳 Pluralsight Courses ► https://codinghelmet.com/go/pluralsight
📸 Udemy Courses ► https://codinghelmet.com/go/udemy
📸 Join me on Twitter ► https://twitter.com/zoranh75
🌐 Read my Articles ► https://codinghelmet.com/articles
📸 Join me on LinkedIn ► https://www.linkedin.com/in/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 YouTube channel, you can find shorter video forms focused on clarifying practical issues in coding, design, and architecture of .NET applications.❤️
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
⚡️RIGHT 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 YouTube 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
Here is one riddle for you today.
The C# syntax has been changing steadily for the last 20 years.
Why did it change in this way and not in some different way?
That is the riddle I will solve in this video once and for all.
You must have heard that when you start writing your code in F# the size of it will
reduce to one-third of what it was in C#. That is not a joke.
That really happens. Peel your eyes to the screen because now I will do
that same thing in C# using that changed syntax. I bet th
at nobody has shown you this before.
I will write a C# method that does some calculation the old-fashioned way.
Then, I will rewrite it several times, adding more and more of the latest C# syntax
and you will see how short my code will become. This method is my first attempt.
The process will be straightforward. I'm preparing to iterate through the strings.
I must put the enumerator into the using block because data might come from a disposable source.
While there are strings I will try to pars
e them into an integer number, putting them into a list.
You see that this is a foreach loop, don't you? But I had to show you what lies
inside the foreach loop when it works with a disposable resource.
The rest will be straightforward. I must find the sum of the two
largest numbers in the sequence. You don't have to read what this code is doing.
Just read the structure of the code. So, I have initialized an array of two
elements, put the first two elements from the input sequence in sorted o
rder, and then
I'm iterating through the rest of the data. This kind of code - that is
where we find so many bugs. This is the magnet for bugs.
The incoming number might be a candidate for the winning places.
There are two possible changes in the order of candidates.
Again, don't try to figure what is the algorithm, just read the syntax, read how
I'm structuring this arithmetic piece of code. So, it is done.
Does your code look like this? Does it have this indentation structure?
This is the 2
0th century code, so I ask you again: does your code look like this?
This code has many issues. It is procedural and procedural
code is a magnet for bugs. It is also exceptionally verbose,
taking a lot of vertical space. I did exaggerate a bit by not using
foreach above but the problem remains: this code is verbose and risky.
It risks having bugs. So, let me start another attempt at solving
the exact same problem using modern syntax. First, I will use a target-typed
new expression this time
. You can forget declaration
like list list is new list. Name the variable after
its role, not by structure. And use target-typed new expressions so
there will be no needless repetition. Use object initializers to tell
everything else in a very condensed form. C# 8 gave us the using declarations to relieve
us from one extra pair of curly braces. Anyway, as I said, it is
the foreach loop I wanted. Inside of it, I used to pass each
string into a new integer variable. What variable?
Oh, the
one I will declare inline. Another line of code gone.
Things will now start to accelerate. Instead of an old-fashioned C-like
array I will use tuple literal syntax. It is the ValueTuple object behind the scenes.
This line of code also demonstrates deconstruction because it is not
the tuple I assign to on the left. It is just two variables.
I can condense this declaration further by using the var keyword.
Then comes another improvement everyone should use: LINQ.
Stop struggling with indexes, st
op making bugs. Combine foreach with LINQ to
get an iteration variable again. I'm using tuples and deconstruction
to make this method very dense. Some will complain about this syntax.
Split these two lines into four if that is what you want, I don't mind.
Still, this is the entire method that does everything the prior one did, only this one is
removing one out of three lines of code from it. But I can do more, way more!
The next phase in development will include the modern C# but also
the mo
dern C# thinking - the mindset. If you're still doing the old-fashioned C#,
this will be the roller coaster for you. Here is what I'm talking about.
The original method had 30 lines of code without blank lines, containing six pairs
of curly braces, totaling 18 lines of code that effectively does the work.
Now, the second variant. It had only 17 lines of code, including
two pairs of curly braces, making it 13 lines of effective code.
And then it will begin. The upcoming transform, which I'm ju
st about
to begin writing, will end up being only 15 lines long, 11 lines of code effectively.
And then, the bonus lesson will come. I will ask you to subscribe to my
channel before I show you that code. It is a secret.
I will show you an ultimate form that is by 60% shorter than the original.
Not everyone can read that final code which I'm going to produce, let
alone appreciate its qualities. But it will be C# nonetheless, the modern C#.
Strap up your seat belt, here it begins. The intermedi
ate step will be to acknowledge
that every loop maintains a state. There's a finite state machine, the
state of which changes from iteration to iteration until it comes to an end.
This thinking is abstract, academic maybe, but it is straightforward.
Don't judge it. Figure it out first, then judge it.
Each loop iteration will apply one item from the input to the state machine.
This is the form of looping I want you to see. There are no loops.
There are only transforms that are applied under the
influence of the incoming items.
And that will open your mind up to LINQ, because LINQ will loop.
You will just give the transform. Now start thinking in that way.
Use continue to remove another pair of curly braces inside the loop.
And then comes the revolutionary step. Use the new switch expression
to advance to the next state. Each hand in the switch
expression will be one pattern. If the count is zero, this is the first item
and it takes its position in the next state. Again, forget the
algorithm.
This is the arithmetic transform, you don't have to focus on that.
Focus on the structure of my code, how I am doing arithmetic transforms this way.
Now look at it. What you see here is the
pattern matching expression. Are you thinking in terms of pattern matching?
I'm asking you because you should be thinking in terms of pattern matching expressions.
So, again, are you thinking in pattern matching. That is the modern C#.
Now, to the final, most magnificent stage. This method is over
.
Now comes the point. Before you step to watching the last, the
final transformation I have prepared for you, you must subscribe to my channel.
I don't want just anyone to watch this. Also you can subscribe to my Patreon page
if you wish to download the source code from this video and all other videos on my channel.
And you can join the Discord server associated with this YouTube channel where you can
take part in discussions and ask questions. All the links are in the description.
One last
warning and then I will begin. If this what you have seen so far
is too much for you then just stop. It's fine.
I want to show you what I would do in F#, only using the C# syntax.
It is perfectly fine if you're not ready for that. You can learn it in smaller steps
from other videos on my channel. Now, if you are determined to keep going all
to the end with me, look at this portion here. What is it?
It is the process of advancing the state machine under the effect of an input number.
Very abst
ract, very academic, but that is what it does.
Let me put it into a separate method. Functional programmers would
call this a pure function. That is the function which doesn't make any side
effects and doesn't depend on any mutable state. Tuples and switch expressions
let me do this easily. I'm also using tuple patterns and discard
patterns here to avoid clumsy if conditions. The next step is dealing with raw
data before strings become ints. Good, why don't we put it into another method?
An
other pure function which doesn't make any side effects.
Expression-bodied methods are another giant improvement - no curly braces anywhere.
One more preparatory step remains. A method that produces an effective result.
This was the expression and here comes the method. Are you prepared for the pinnacle of
this demo in which I will turn this entire method into a single line of code,
a single expression and a very short one. One-liner, I promise.
Watch this. Generic IEnumerable will help.
IEnum
erable is the most magnificent interface in .NET.
Expression-bodied method, no curly braces. LINQ, of course.
Tuples, always tuples. Then I pass the method groups
in, converted to delegates. And my work here is done.
It's all on the compiler to figure this out and to compile it.
What you see here is the C# today. Pure functions, the way we write them in F#.
All branching done via pattern matching. All looping done via LINQ.
All behavior done via expressions. I told you it won't be easy if you'r
e not
accustomed yet to this way of thinking. We do need a few more syntactic
improvements to clean this code further. But even this is way ahead of what I had in
the first function, the first method I made. One pair of curly braces instead of six pairs. Twelve lines of code instead of 30.
Start thinking in this way. And if you want to learn more about how to
use C#, the modern C# effectively, stay here, subscribe to my channel, and watch other videos.
Watch this video next, for example.
Comments
I would argue that code readability is far more important than reducing the code by 3, 5, or even 10 lines. Not to mention, that the code should be easy to debug. It seems like a challenge to make the code as short as possible which might be suitable for Codewars, but not for production code. So I would use "syntax improvement" that are really syntax improvements - that will show the intent and keep code readable and easy to debug.
I adore all your lectures, including on Pluralsight. You have truly changed my programming style/vision/life and my code is 10x less buggy than it was 10 years ago! Zoran Guru of Functional Programming! IoC + Interfaces + Linq + SOLID + Functional Programming (no loops, no deep branches, no cyclomatic complexity, only Linq and self-described small methods) == Success. Thanks a lot!
I like how your videos summarize most of the features from any C# versions, especially the new ones. I've seen the "when" keyword before, but never understood its use until now, same for using switches to declare variables.
As he says; F# is even more readable (preferable?). Here is a variant: let tryParse (input:string) = match System.Int32.TryParse input with | true, v -> Some v | _ -> None let produceSum (input:int seq) = match input |> Seq.toList with | [max; next; _] -> max + next | _ -> - 1 let sumGreatestTwo (input:string seq)= input |> Seq.choose tryParse |> Seq.sortDescending |> produceSum
I watch your videos time to time, and I have to admit that each time I watch I appreciate more the content, because I understand the code and the use-cases where I would use these techniques. You're a great mentor, I've started learning from your videos in the beginning of my career, now I feel happy to have materialized that knowledge.
Zoran Im a active Patreon subscriber and your videos are always helpful!. To be honest your videos make me uncomfortable (in a good way). It pushes me to find my gaps and progress my abilities. Thank you!
I like a lot your channel and your functional approach. I've been trying to do my code like this for years
I think I would've clumsily reduced it to about 6 Linq statements. Something like: var result = items .Select(n => int.TryParse(n, out var val) ? (int?)val : null) .Where(n => n.HasValue) .OrderByDescending() .Take(2) .ToArray(); return result.Length == 2 ? result.Sum() : -1;
Thanks! It was hard but very exciting!
Your videos are very educational. Keep up the good work!
I like the last example. I think the difficulty lies in the lack of understanding of the Aggregate method more than the code itself.
very interesting video, i myself try to use some more modern syntax of csharp, it is usually an iterative process, balancing human readability, syntax and performance
I like using these tricks to shorten my code, but I've noticed that sometimes it has a tendency to make the code less readable, so I try to balance those things
Awesome techniques. Very educational. Thank you for your effort!
I do the FP styled code most of the time in my daily work, including using method groups as delegates (especially so even). My personal style is to do a bit less in expression bodied methods as i find the fellow who didn't write it lay struggle to read it, also still haven't taken the time to use all the Linq methods i could. Though my past experiences affect that as i used to write code where an IEnumerable was an ungodly memory hog very easily and Linq methods could easily box in not just the obvious variable but half a function chain. Learning off the aversion where appropriate (even the C#12 Linq simply doesn't hold a candle to careful proc code on blazing paths, but those are slow to write without bugs)
I really enjoyed this video. It's a great overview of modern programming and oddly enough I'm currently looking into functional programming to see if I can snatch paradigms and bring them over to C#. My main question as a game developer... do I need to be concerned for performance employing such a style of programming?
My worry with C# having so many different ways to do things in the same language is that when you have a shared code base with lots of different people, there will be lots of different "flavours" or styles and implementation techniques using different styles of the language ... i.e its going to encourage inconsistency. But then on the flip side, it makes the language so powerful and means it can be used in more places. So yes, I'm not entirely sure how I feel about the current direction of C#.
Happy new year!! Now, I can be free to use "when" clause in switch expression body and many thanks for great tutorial. Btw, it seems the seed values for the max and the next in functional variations should be int.MinValue instead of 0.
if I saw the last approach in a PR I would nope out
string[] nums= ["1","2","3","4","NAN","77","dude","23"] // modern syntax i prefer is 4 lines int sumlargest2 = nums.Select(x=>int.TryParse(x,out int i32)?i32:0) .OrderByDescending(i=>i) .Take(2) .Sum();