Introducing Functional Programming Using C#: Leveraging a New Perspective for OOP Developers 1st Edition Vaskaran Sarcar download
Introducing Functional Programming Using C#: Leveraging a New Perspective for OOP Developers 1st Edition Vaskaran Sarcar download
or textbooks at https://ebookmass.com
https://ebookmass.com/product/introducing-functional-
programming-using-c-leveraging-a-new-perspective-for-oop-
developers-1st-edition-vaskaran-sarcar/
https://ebookmass.com/product/introducing-rescript-functional-
programming-for-web-applications-1st-edition-danny-yang/
https://ebookmass.com/product/programming-principles-and-practice-
using-c-second-edition-stroustrup/
https://ebookmass.com/product/programming-principles-and-practice-
using-c-2nd-edition-ebook-pdf/
https://ebookmass.com/product/programming-for-absolute-beginners-
using-the-javascript-programming-language-1st-edition-jonathan-
bartlett/
Introducing
Functional
Programming
Using C#
Leveraging a New Perspective for
OOP Developers
—
Vaskaran Sarcar
Introducing Functional
Programming Using C#
Leveraging a New Perspective
for OOP Developers
Vaskaran Sarcar
Introducing Functional Programming Using C#: Leveraging a New Perspective for
OOP Developers
Vaskaran Sarcar
Kolkata, West Bengal, India
Introduction�����������������������������������������������������������������������������������������������������������xvii
v
Table of Contents
vi
Table of Contents
vii
Table of Contents
viii
Table of Contents
ix
Table of Contents
Index��������������������������������������������������������������������������������������������������������������������� 297
x
About the Author
Vaskaran Sarcar obtained his master’s degree in software
engineering from Jadavpur University, Kolkata (India),
and his master’s of computer application from Vidyasagar
University, Midnapore (India). He was a National Gate
Scholar (2007–2009) and has more than 12 years of
experience in education and the IT industry. He devoted
his early years (2005–2007) to the teaching profession at
various engineering colleges, and later he joined HP India
PPS R&D Hub in Bangalore. He worked at HP until August
2019. At the time of his retirement from HP, he was a senior software engineer and team
lead. Vaskaran is following his passion and is now a full-time author. You can find him on
LinkedIn at https://www.linkedin.com/in/vaskaransarcar and see all of his books at
https://amazon.com/author/vaskaran_sarcar.
xi
About the Technical Reviewers
Leandro Fernandes Vieira is a senior software engineer
currently working for a leading payment solutions company.
He earned his degree in system analysis and development
from São Paulo State Technological College (FATEC-SP),
Brazil. His realm of expertise includes the .NET stack and
the C# and F# programming languages. He has a passion
for programming and algorithms and likes to contribute
to open-source projects; in fact, he is a creator of the
RecordParser project, one of the fastest CSV parsers for .NET.
He enjoys spending time with his family, walking in the park, hitting the gym, and
listening to heavy-metal music.
You can reach him at https://github.com/leandromoh/.
xiii
Acknowledgments
I thank the Almighty. I sincerely believe that only with His blessings could I complete
this book. I also extend my deepest gratitude and thanks to the following people:
• Leandro Fernandes Vieira and Paul Louth: They allowed me to use
the Curryfy library and language-ext library in this book. Leandro
also joined the technical review team and provided many useful
suggestions and improvements for this book.
• Shon, Kim, Nagarajan, and Vinoth: Thanks to each of you for your
exceptional support to improve my work.
Finally, I thank those people from the functional programming community who have
shared their knowledge through online blogs, articles, courses, and books.
xv
Introduction
Throughout the ages, prophets have suggested that most of us are not reaching our full
potential. If you look at the great achievers in any field in the current world, you will find
that they are hard workers, and they strive to keep improving. They put in extra effort to
improve their skills, and in many cases, they even hire coaches to learn new techniques.
Then, one day, they discover that all their hard work starts to pay off: they become
masters in their chosen field.
The following quote from the Chinese philosopher Confucius perfectly
summarizes this:
The will to win, the desire to succeed, the urge to reach your full
potential…these are the keys that will unlock the door to personal excellence.
Now let’s apply this philosophy to programming. As a developer, are you reaching
your full potential with C#? I may not know your reply, but I certainly know my answer.
Even after working with C# for more than 14 years, there is still more to learn.
One evening I asked myself, how could I improve my C# skills? I could continue
to try to learn new features and practice them, but intuitively, I knew there was an
alternative answer. So, I started searching for tips and eventually discovered that most of
the time I was using C# for object-oriented programming (OOP). Indeed, it is a perfect
fit for OOP, and there is nothing wrong with this tendency. But what about functional
programming (FP) using C#? It’s not that I never used it (in fact, C# developers are very
much familiar with LINQ), but I was not very conscious of it. So, I keep browsing through
various resources, such as books, articles, and online courses. Eventually, I discovered
that during its development, C# started embracing functional features too, and as a
result, it has become a powerful hybrid language.
I became very interested in the topic and tried to learn more about it. From this
time onward, I started facing challenges. There were some good resources, but I could
not stitch them together to serve my needs. This is why I started documenting my notes
when I was experimenting with using C# in a functional way. This book is a result of
those efforts.
xvii
Introduction
So, welcome to your journey through Introducing Functional Programming Using C#:
Leveraging a New Perspective for OOP Developers.
C# is a powerful programming language, is well accepted in the programming world,
and helps you make a wide range of applications. These are the primary reasons it is
continuously growing in popularity and is always in high demand. So, it is not a surprise
that existing and upcoming developers (for example, college students and programming
lovers) are curious to learn C# and want to create their applications using it.
Many developers try to learn it in the shortest possible time frame and then claim
they know C# well. In fact, many resources claim you can unlock the real power of C# in
a day, a week, or a month. But is this true? I think not. Remember, I’m 14 years in and I’m
still learning.
Malcolm Gladwell’s 10,000-hour rule says that the key to achieving world-class
expertise in any skill is, to a large extent, a matter of practicing the correct way, for a total
of around 10,000 hours. So, even though we may claim that we know something very
well, we actually know very little. Learning is a continuous process, with no end to it.
Then should we stop learning? Definitely, the answer is no. There is something called-
effective learning. It teaches you how to learn fast to serve your need. This is the context
where I like to remind you about the Pareto principle or 80-20 rule. This rule simply states
that 80% of outcomes come from 20% of all causes. This is useful in programming too.
When you truly learn the fundamental aspects of FP, you can use it effectively to improve
your code. Most importantly, your confidence level will raise to a level from where you
can learn more easily. This book is for those who acknowledge this fact. It helps you to
understand the core principles of FP with plenty of Q&A sessions and exercises.
• Part I consists of the first three chapters, which start with an overview
of functional programming (FP). Then we’ll discuss functions and
immutability in depth. These are the building blocks for FP and what
you need to understand to move on to Part II of this book.
• C# is a multiparadigm language, and Part II reveals its potential.
This part will cover how to harness the power of FP. In addition,
two well-known external libraries, called Curryfy and language-ext,
xviii
Introduction
are discussed in this part. The first one is used in Chapter 5 when I
discuss currying. The second one is used in Chapter 8 and Chapter 9
when I discuss functional error handling and the Monad pattern.
The best way to learn something is by analyzing case studies, asking questions
about any doubts you have, and doing exercises. So, throughout this book, you will see
interesting code snippets, “Q&A Sessions,” and exercises. Each question in the “Q&A
Sessions” sections is marked with <chapter_no>.<Question_no>. For example, 5.3 means
question 3 from Chapter 5. You can use the simple exercises to evaluate your progress.
Each question in these exercises is marked with E<chapter_no>.<Question_no>. For
example, E6.2 means exercise 2 from Chapter 6.
The code examples and questions and answers (Q&As) are straightforward. I believe
that by analyzing these Q&As and doing the exercises, you can verify your progress.
They are presented to make your future learning easier and more enjoyable, but most
importantly, they will help you become confident as a developer.
You can download all the source code of the book from the publisher’s website,
where you can also find an errata list for the book. I suggest that you visit that website to
receive any important corrections or updates.
Prerequisite Knowledge
The target readers of this book are those who want to make the most of C# by harnessing
the power of functional programming. I expect you to be familiar with .NET, C#, and
OOP concepts. In fact, knowing about some advanced concepts such as delegates
and lambda expressions can accelerate your learning. I assume that you know how to
compile or run a C# application in Visual Studio. This book does not invest time in easily
available topics, such as how to install Visual Studio on your system, how to write a
“Hello World” program in C#, and so forth. Though I have used C# as the programming
language, if you are familiar with a similar language like Java, you can apply that
understanding to this book.
xix
Introduction
• Are you familiar with .NET, C#, and basic object-oriented concepts
such as polymorphism, inheritance, abstraction, and encapsulation?
• Are you interested in knowing how the core constructs of C# can help
you in FP?
You probably shouldn’t pick this book if the answer is “yes” to any of the following
questions:
Useful Software
These are the important tools that I use in this book:
• While writing this book, I had the latest edition of Visual Studio
Community 2022 (64-bit, version 17.5.4). All the programs were
tested with C# 11 and .NET 7.
xx
Introduction
• The community edition is free of cost. If you do not use the Windows
operating system, you can still use the free Visual Studio Code, which
is a source-code editor developed by Microsoft to support Windows,
Linux, or Mac operating systems. At the time of this writing, Visual
Studio 2022 for Mac is also available, but I did not test my code on it.
• This book suits you best if you are familiar with some advanced
features in C# such as delegates and lambda expressions. If not,
please read about these topics before you start reading this book.
• The code in this book should give you the expected output in future
versions of C#/Visual Studio as well. Though I believe that the results
should not vary in other environments, you know the nature of
software: it is naughty. So, I recommend that if you want to see the
exact same output as in the book, you mimic the same environment.
• You can download and install the Visual Studio IDE from https://
visualstudio.microsoft.com/downloads/ (see Figure I-1).
xxi
Introduction
Figure I-1. Download link for Visual Studio 2022, Visual Studio for Mac, and
Visual Studio Code
Note At the time of this writing, this link works fine and the information is
correct. But the link and policies may change in the future. The same comment
applies to all the links mentioned in this book.
Source Code
All the source code used in this book can be found at https://github.com/apress/
introduction-functional-programming-cs.
xxii
Introduction
I’ve used top-level statements heavily in this book. Consequently, there is no need
for me to explicitly write the Main method for console applications. You understand that
using this technique, I minimized the code lengths. When you use top-level statements,
the C# compiler does the necessary job on your behalf in the background. Top-level
statements have been supported since C# 9.0.
I also like to add that I enabled implicit usings for my C# projects. The implicit
usings feature automatically adds common global using directives for the type of
project you are building. Starting from C#10.0, this feature is also supported. Otherwise,
I had to add the necessary directives to my programs manually.
Finally, all the output/code in the book uses the same font and structure. To draw
your attention in some places, I have used bold fonts. For example, consider the
following output fragment (taken from Chapter 3 where I discuss external immutability):
Final Words
Congratulations, you have chosen a programming language to experiment with a
paradigm that will assist you throughout your career. As you learn and review these
concepts, I suggest you write your code instead of copying and pasting it; there is no
better way to learn.
Upon completing this book, you’ll be confident about FP and the value it
provides you.
xxiii
PART I
In brief, these are the building blocks for FP and the foundations you’ll need to
understand before reading Part II of this book.
CHAPTER 1
Functional Programming
Overview
You can reach a destination using different vehicles. If the destination is well connected
to transportation routes, you can use a car, a bus, a train, or an airplane. If the destination
is nearby, you may opt for a bicycle. If you are health conscious, you may prefer to walk.
This is simple to understand. Now think about some special scenarios: you need to
reach your destination as soon as possible, but it is not a nearby location. Are you going
to walk? The answer is no. In a situation like this, you will want to use a vehicle to reach
your destination faster. But when you are not in a hurry or want to avoid a crowded bus,
you may prefer to walk. Depending on the context, one approach might be a better fit
compared to others.
The programming world is no different. You can use different programming styles
to create the same application. Each approach has its pros and cons. Based on the given
constraints in an application, you might prefer one approach over another. If you are
aware of multiple routes, you can choose the approach that suits your needs best.
3
© Vaskaran Sarcar 2023
V. Sarcar, Introducing Functional Programming Using C#, https://doi.org/10.1007/978-1-4842-9697-4_1
Chapter 1 Functional Programming Overview
So, using C#, you can also combine different styles of coding in an application.
Most importantly, to implement the key ideas in functional programming (FP), you can
use C# instead of learning a new programming language. Throughout the book, we’ll
look into these possibilities.
Now it is clear that conceptually a method and a function are the same. You see this
terminology difference because these two different paradigms treat functions differently.
In this book, we are exploring functional programming. So, I’ll be using the term function
instead of method in the corresponding places.
In Chapter 2, you’ll see that in addition to the traditional methods, there are other
ways to represent functions.
4
Chapter 1 Functional Programming Overview
Q&A Session
1.1 C# primarily follows OOP, but you are using it in the functional style. This helps
us avoid learning a new programming language, but are you saying that learning an
FP-based computer language is a bad idea?
Not at all. Developing your knowledge and learning a new programming language
are always good ideas. If you know functional languages like F# or Haskell, no one is
restricting you from using them. But in a real-world project, you may not have that
freedom. For example, if you are working on a project that uses only C#, you have
only one option: coding with C#. But C# is a multiparadigm language, and it supports
functional programming. This means that by using some of its features, you can bring
the power of functional programming to an existing project.
Second, you may not have the time or motivation to learn a new programming
language to fulfill some specific needs in a project. In such cases, it is always helpful to
implement the concept using known features.
Finally, many existing features in C# have been developed following the functional
style of coding. Instead of blindly using them, if you understand the context, you can
enjoy your learning.
Important Characteristics of FP
Though FP is a programming paradigm, it does not specify how the concepts should
be implemented in a programming language. As a result, a programming language that
follows FP can support many different features to implement these concepts. At a high
level, FP has the following characteristics:
• It prefers immutability.
Let’s take a quick look at these bullet points. You can surely guess that we’ll cover all
these points in more detail in the upcoming chapters.
5
Chapter 1 Functional Programming Overview
In C#, delegate types can represent functions. If you are familiar with Func (or
Action) delegates or if you are a lambda lover, probably you know this answer, and you
are already familiar with the usage.
To clarify, let’s consider the Func<int,int> type. You know that this is a delegate type
and it encapsulates a function that accepts one int parameter and returns a value of type
int. Let’s consider a sample line of code that is as follows:
Since the function is assigned to the variable doubleMaker, a developer can write
something like int result = doubleMaker(5);.
You can also pass this function to another function. Demonstration 1 shows such
a usage.
Demonstration 1
In the following program, doubleMaker is an instance of Func<int, int>, and it is used
as a variable. I pass this variable to another function, called GetResult.
6
Chapter 1 Functional Programming Overview
Note I remind you that I have heavily used top-level statements and enabled
implicit usings for the C# projects in this book. These features came in C#
9.0 and C#10.0 respectively.
int temp = 5;
Func<int, int> doubleMaker = x => x * 2;
int result = Container.GetResult(doubleMaker,temp);
WriteLine(result);
Output
The output is easy to predict. Since I have passed the integer 5 as an input (along with
the function variable doubleMaker), the program outputs 10.
Analysis
Let’s analyze the key steps in this program. First I declare a function using a delegate
and name the function variable doubleMaker. I then pass this variable to invoke the
GetResult function. So, the following points are clear:
7
Chapter 1 Functional Programming Overview
Author’s note In Chapter 3, you’ll see different variations of immutability. But in every
case, the core idea is the same: once you make a type that does not allow continuous
changes to its state (or the state of its instances), it is considered immutable in some sense.
Demonstration 2
Suppose I have a program that starts with a list of names. Later, I clear the content of this
list and add new names. The following program demonstrates this:
8
Chapter 1 Functional Programming Overview
Note Removing the lambda expression, you can simply the line names.
ForEach(x => WriteLine(x)); as names.ForEach(WriteLine);.
Output
Let’s verify the output.
You can see that the list contained two names, Sam and Bob, in the beginning.
Later I cleared the content of this list and added two new names. This kind of update
is called a destructive update because you have lost the original content. The situation
can be worse if you encounter runtime exceptions. FP does not like this. It prefers
immutability. The key idea is that once created, variables should not be reassigned or
modified.
Now think for a moment: if you work on immutable variables, you know that once
initialized, these variables cannot change their values. So, the term variable does not
make sense in those contexts. This is the reason you will hear the term value instead
of variable in functional programming.
Q&A Session
1.2 How does immutability fit into functional programming?
9
Chapter 1 Functional Programming Overview
1.3 While discussing destructive updates, you said that the situation becomes worse
if you encounter runtime exceptions. Can you give an example to demonstrate such
a situation?
Consider Demonstration 3.
Demonstration 3
To answer the previous question (1.3), I’m going to modify Demonstration 2.
Let’s assume that the program needs to display the names along with the number of
characters that are present in the name. The following is a typical implementation that
contains a possible bug. Why is there a possible bug? I start with a list of names called
names, and then I use the following code segment in this program:
You can see that before I add a name to the list, I generate a random number. If the
number is greater than 0, I’ll add this name; otherwise, I’ll add a null. (Yeah, I know, it is
bad! But I want to produce the bug easily.)
Here is the complete program (notice the important changes in bold):
10
Chapter 1 Functional Programming Overview
Output
Here is some sample output when everything goes well and it was able to add a new
name successfully:
But based on the generated random number (when it is 0), this program can throw
the following runtime exception:
Analysis
This program shows that a destructive update can raise a runtime error. As developers,
we do not like to see a program crash at runtime. FP’s philosophy is simple: avoid
destructive updates. When I discuss immutability in depth in Chapter 3, you’ll see that
we can avoid this kind of update in our program.
11
Chapter 1 Functional Programming Overview
Which functions are pure? The previous link states that a function is pure if it
satisfies the following characteristics:
• It’s consistent. Given the same set of input data, it will always return
the same output value.
• It has no side effects. The function does not change any variables or
data of any type outside of the function.
The function that does not satisfy any of these conditions is called an impure
function.
Demonstration 4
You will learn more about purity and side effects shortly. For now, it will be sufficient if
you understand the following program:
WriteLine(AddFiveTo(2));
WriteLine(GetRandomNumber(2));
Output
Here are some probable outputs from this program:
Sample Output-1:
7
3
12
Chapter 1 Functional Programming Overview
Sample Output-2:
7
6
Sample Output-3:
7
4
And so on. You can see that given input 2, GetRandomNumber returns different values.
Since the result is inconsistent, you can conclude that this is an impure function.
Now, look into the AddFive function. You can see that AddFiveTo is consistent; it
always returns 7 if the input is 2. You can also see that this function depends on the
supplied input only; it does not change any variables or data of any type outside of the
function. So, this function does not have any side effect. Since both conditions for purity
are satisfied, we can conclude that AddFiveTo is a pure function.
• Case 4: Your function accepts user input and prints some message in
a console window.
The first two cases are easy to understand: they cause side effects. Why? In each case,
you mutate the values. As a result, given the same input, the same function produces
different outputs. You may still wonder about case 3 and case 4. Let’s take a look at them.
To demonstrate case 3, I’ve written the following function inside the Sample class.
Obviously, it is bad.
class Sample
{
public static int GetResult(int a)
{
13
Chapter 1 Functional Programming Overview
The first problem is obvious: you cannot predict the result in advance. For example,
the following line:
can give you valid data, or it can raise the following exception (when the divisor
random becomes 0): System.DivideByZeroException: 'Attempted to divide
by zero.'
Throwing an exception always forces you to think about gracefully handling the
exception; otherwise, your program crashes, which is an example of the worst possible
side effect. In fact, exceptions indicate indeterminism in the code.
I discuss case 4 in the section “Functions with I/O,” which is coming next.
Console.WriteLine("Enter a number:");
Did you notice that the state of the system has changed, and returning the system
to its previous state is impossible now? You can see that when a function needs to
depend on the external world, there is no escape. You may argue that this is an intended
14
Chapter 1 Functional Programming Overview
scenario, but following the FP paradigm, it is still considered a side effect. In fact, a
purely mathematical function often needs to communicate the result using the I/O.
So, some of your code segments will have to be impure.
Now the next question is, which part of the code segments can be impure? A common
guideline for this type of situation is that you should try to separate the functions that
perform the I/O from the functions that perform the actual computation. The functions
that perform those computations should be the pure function in the functional world. In
C#, we can mix them, but to follow a functional style of coding, keep this suggestion in
your mind.
In this book, I often compare OOP-style coding with an equivalent functional style
of coding with complete programs. When I refactor the imperative code to functional
code, I focus on the key aspects. Normally, I do not change the Main method (aka
function) that handles the I/O operations. Remember, since I use top-level statements to
demonstrate programs, you will not explicitly see the presence of the Main method. For
example, in .NET 7, I can run a program that consists of a single line as follows:
Console.WriteLine("Hello, reader!");
This is a big simplification compared to older versions of C#, where you need to
explicitly define the Main method and use the “using statements” at the beginning of
your file.
Author’s note If needed, you can learn about top-level statements at https://learn.
microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/top-level-statements.
POINT TO NOTE
In the OOP style, it is a common practice to encapsulate data and methods inside a class. But
in the functional style of coding, it is common to separate the functions from the data. The
discussion of side effects should give you the idea that FP encourages us to work on pure
functions and minimize the side effects.
15
Chapter 1 Functional Programming Overview
• Impurity does not always indicate something bad. Also, side effects
are often desirable in certain places. To illustrate this, let’s consider
the example of a database update or consider the case where you
work with a function that logs data including the current date and
time. What do you think about these operations? You understand
that to bring the theoretical “concept of purity,” you cannot introduce
unwanted complexities and compromise the overall performance of
your program.
The key idea is that you should avoid side effects as much as possible to make your
code more maintainable. For example, you can isolate the I/O operations from the
actual computations. (You will learn more about this in Chapter 6 when I discuss the
Functional Core, Imperative Shell pattern.) Keeping a similar goal in mind, when you
refactor a code where the user interface (UI) layer talks to the business logic layer, you
first attempt to minimize the side effects in the business logic layer.
16
Chapter 1 Functional Programming Overview
POINT TO REMEMBER
In the context of purity and side effects, you can remember the following points:
• This means we cannot control every possible side effect. In general, you should
focus on those parts that you can control.
• Finally, you should not conclude that an impure function is a bad thing. In OOP,
you probably have seen that we want dynamic behavior in many applications, and
that behavior is very much desirable there. In fact, a normal program that tries
to update a database has a “desirable” side effect. Here we are studying pure
functions following the formal definitions, and this is the reason we are focusing
on purity. As you progress on this topic, these topics will be clearer to you.
Q&A Session
1.4 Why does FP like pure functions?
There are many reasons behind this. Let me show you some of those benefits:
• Since these functions result in the same output, you can write test
cases against a consistent or reliable output.
• This consistent nature can provide you with huge benefits when you
focus on parallelization.
In fact, once you get the result from an execution of a pure function, you can avoid
the further execution of this function. This is because, once computed, this computed
value will not change anymore.
17
Chapter 1 Functional Programming Overview
behavior in advance. So, these side effects compromise the understandability of the code
too. In addition, if you work in a multithreaded environment and have methods that
cause side effects, you need to worry about thread synchronizations. It is because you
know that mutable variables lead to implicit dependencies and can cause a lot of nasty
bugs, particularly in a concurrent program.
Demonstration 5
I will now show you a sample program that follows an imperative style of coding.
OOP developers are quite familiar with this style. Given a list of numbers, the following
program picks the numbers that are greater than 30 (notice the important segment
in bold):
Output
This program produces the following output:
Now let’s see how a functional programmer can write an equivalent program.
Functional programmers like to use expressions, not statements. Why? This choice
makes the code more declarative. Probably you know that System.Linq in C# is
functional in nature. So, a functional programmer may like to use the built-in support
and refactor the previous program; this is shown in the following demonstration.
Demonstration 6
Here is the refactored program (notice the important changes in bold):
19
Chapter 1 Functional Programming Overview
Output
It should be no surprise that you see an equivalent output (that you saw in
Demonstration 5):
Q&A Session
1.6 You said that FP developers prefer the declarative style of coding. Do you think
that the declarative style is better than the imperative style?
No. Each approach has its pros and cons. Remember that our goal is to take the best from
each approach.
Let’s see the advantages of the declarative style of coding. The imperative style
instructs how to perform the computation, so the order of execution of the statements is
important. But the declarative style focuses on what to be computed, not on “how it’s to
be computed.” So, it helps you vary the function invocation calls. For example, given
the list shown in the previous demo, each of the following code segments (segment-1
and segment-2) will produce the identical result (notice that I have altered the function
calls in the top two lines in these segments):
// Segment-1
numbers.Where(x => x > 30)
.Select(x => x)
.ToList()
.ForEach(x => Write(x + "\t"));
20
Chapter 1 Functional Programming Overview
// Segment-2
numbers.Select(x => x)
.Where(x => x > 30)
.ToList()
.ForEach(x => Write(x + "\t"));
1.7 I am not very familiar with LINQ. Can you compare imperative versus
declarative programming with another example?
I suggest you learn and test some basic operations using LINQ. These will help you
understand this book and functional programming better. If you are not familiar with
LINQ, let me show you another example.
I assume every OOP developer is familiar with if-else constructs. Consider the
following code where the program starts with an integer (flag) that has the initial value
0. Then I generate two random numbers, random1 and random2, and display them.
So, you’ll see the following code:
int flag = 0;
int random1 = new Random().Next(0,2);
int random2 = new Random().Next(10,15);
WriteLine($"The random number 1 is: {random1}");
WriteLine($"The random number 2 is: {random2}");
Later I’ll evaluate two if conditions. If random1 is an even number, I’ll increment the
flag value by 1. Then I’ll check whether random2 is greater than or equal to 13. If this
condition is satisfied, I’ll increment the flag value by 2. Here is the code:
if (random1 % 2 == 0)
{
flag++;
}
21
Chapter 1 Functional Programming Overview
Now let me write an equivalent code using expressions. This time I use the ternary
conditional operator (I renamed flag to flag1 and kept both program segments in the
same file for your comparison purposes):
int flag1 = 0;
flag1+=(random1 % 2 == 0 ? 1 : 0)
+ (random2 >= 13 ? 2 : 0);
WriteLine($"The flag1 is:{flag1}");
You can see that two if blocks are replaced with two lines of code now (for better
readability I made two lines; otherwise, they could be accommodated in a single line
too). This example shows that declarative code can help you write concise code.
Demonstration 7
Here is the complete program that shows the usage of all the parts that I discussed:
#region declarative
int flag1 = 0;
22
Chapter 1 Functional Programming Overview
flag1 += (random1 % 2 == 0 ? 1 : 0)
+ (random2 >= 13 ? 2 : 0);
WriteLine($"The flag1 is: {flag1}");
#endregion
Output
Here are some sample outputs to demonstrate that both approaches produce the
equivalent output (notice that flag values range from 0 to 3):
Sample output-1:
The random number 1 is: 1
The random number 2 is: 14
The flag is: 2
The flag1 is: 2
Sample output-2:
The random number 1 is: 0
The random number 2 is: 11
The flag is: 1
The flag1 is: 1
Sample output-3:
The random number 1 is: 1
The random number 2 is: 12
The flag is: 0
The flag1 is: 0
Sample output-4:
The random number 1 is: 0
The random number 2 is: 13
The flag is: 3
The flag1 is: 3
23
Chapter 1 Functional Programming Overview
From this quote, you can understand that OOP developers primarily follow the
imperative style of coding to make their applications. You will also notice that to
emphasize declarative coding that FP lovers like to use a single expression (remember
the use of LINQ?) instead of using a series of statements. Since we already covered
imperative versus declarative style in the previous section, I won’t elaborate on
this again.
POINT TO REMEMBER
OOP follows the imperative style of coding where you instruct the computer by saying
something like “Do this and then do that.” This style of coding is also termed algorithmic
programming. But FP follows the declarative style.
The second most important thing is that tracking the state changes plays a vital role
in the imperative approach, but it is nonexistent in the functional approach.
Finally, the classes or structures are the basic building blocks in the imperative style
of coding, whereas functions are treated as first-class citizens and are important in the
functional approach.
I’ll finish this discussion with Michael Feather’s quote (see https://twitter.com/
mfeathers/status/29581296216?lang=en), shown here:
OO makes code understandable by encapsulating moving parts. FP makes
code understandable by minimizing moving parts.
24
Chapter 1 Functional Programming Overview
FP Benefits
FP offers some important benefits to programmers. The following points include some
of them:
• FP promotes shorter and cleaner code. Often these are very readable.
• FP likes pure functions. You can manage and test them easily.
Q&A Session
1.8 At the beginning of the chapter, you told me that I can follow different
programming styles to create an application. Can you let me know about some of the
well-known programming styles?
At a high level, you can consider imperative and declarative as the two major types of
programming. With further research, you’ll see that OOP, procedural programming,
etc., follows the imperative style of coding. Functional programming (FP), logic
programming, etc., follows the declarative style. The wiki at https://en.wikipedia.
org/wiki/Programming_paradigm discusses programming paradigms with supportive
materials. If interested, you can take a look.
25
Chapter 1 Functional Programming Overview
Exercises
E1.1 Can you give examples of some built-in pure functions in C#?
E1.2 Suppose there is a function that demands you pass a file path to show you the
content of the file. Will you consider it a pure function?
E1.3 What do you do when you cannot avoid using an impure function?
E1.4 C# supports first-class functions. What does this mean?
E1.5 This chapter shows that you can assign a function to a variable or pass it as an
argument to another function. Can you write a program where you use a function as a
return type?
E1.6 “A pure function can depend on an impure function.” Is this true?
E1.7 “An impure function can call a pure function.” Is this true?
E1.8 In the following code segment, can you point out the pure and impure functions?
class Sample
{
public static bool OpsDone{get;set;}
— "Oi kuule!… Älä puhu sillä lailla!… Olen pahoillani nyt, kun luulet
että sinua epäilisin petturiksi… Ah, uskon sinun rehellisyyteesi. Vaan
miksi pahottaisin teoillani Jumalan mielen, Jumalan, joka minulle
pelkkää hyvää tehnyt on!… Hän hoivannut on koko elämäni… Nyt
puuttuu enää yksi: Oolavini… Hän senkin aivan pian kotiin tuopi…
Siis älä suutu, kun en tarjoomaasi avainta sinulta nyt ottaa voi!… En
tahdo mielipahaa milloinkaan Hänelle, Kaikkein-Parhaimmalle
tuottaa… Ei kukkakaan pahoita päivän mieltä, kun siltä kauniin
valolahjan saa… Ja minä olen enempi kuin kukka ja Luoja suurempi
kuin päiväpaiste… Vaan anteeksi… sinulla kait on pitkä matka. Oi, älä
huoli minun suruistani, vaan lähde kulkuasi jatkamaan."
— "Minä kaadan."
— "Jos ottaa kovalle viinaksetkin, niin kyllä niiltä mies voimat pois
nitistää. Yhden vuoden ahkeralla harjoituksella jo pääsee niin
pitkälle, että saa juoda kuin vettä, eikä mene päähän tippaakaan…"
— "No vie sua!… Joko sinä olet ehtinyt niin syvältä saada elämää
kiinni!… Mutta se oli mainio keksintö!… Sinusta, Oolavi, tulee kohta
mies."
— "Älä nyt ylpeile!… Kun tulee viimeinen tiukka, niin menet vain
naimisiin kuin poika," — puuttui juopunut Horsma.
Harteva vannoi mahtipontisena:
— "Entäs tutkinto?…"
— "Oi suuri Luoja, hyvä, jalo Isä!… Sinä olet minulle suonut
armossasi enemmän kuin olin toivonutkaan!… Sinä annoit minulle
kaiken mitä voidaan maan päällä edes uneksiakaan: Sinulta olen
saanut vanhempani… Lisäksi annoit lapsuuteni onnen, sen onnen,
jonka armaat, kauniit muistot nyt sielustani hiljaa kumpuavat kuin
armaat ihanimmat unennäöt… Niin: koko minun kaunis nuoruuteni
on ollut täynnä onnen antimia, jokainen aamuni on ollut runoutta…
Ne valkenivat ihmeen ihanina öisistä armaimmista unistani kuin päivä
aamuruskon punervasta… Sinulta sain myös suuren sielunrauhan;
sen päällä lahjanasi leijaelee armaisin surullinen ikävöinti… Niin:
kaiken, kaiken, annoit Sinä, Isä… Siis kiitos niistä lahjoistasi olkoon
Sinulle, Suuri henki, ainiaan!"
— "Muun kaiken saat, jos tahdot pois taas ottaa minulta niin kuin
lainan konsanaan — vain kaksi lahjaasi suo minulle jäädä: Ensiksi
Oolavi ja vanhempani, ja toiseksi järkkymätön usko Sinuun ja Sinun
johdantoosi elämässä… Niin: niitä et saa koskaan ottaa pois. Ja jos
tahdot minua milloin lyödä, niin kuivaa silloin myöskin kyyneleeni ja
älä salli niiden liian karvaiksi minulle, Isä, tulla milloinkaan!… Jos
olen heikko, toki omin voimin voin ehkä itkeä ne kyyneleeni, vaan
Sinulle kuuluu niiden kuivaaminen… Oi, kuule, Isä, kuule Martva-
rukkaa, äläkä salli kenenkään minun tähteni vitsaasi tuta, eikä
suruun jäädä!…"
*****
— "On totta: Suurin osa ihmisistä sen kyllä tietää, mutta harva
muistaa nämä Jumalan sanat Aadamille: 'Otsasi hiessä täytyy sinun
syödä'… Niin moni luulee, että tämä käsky mukamas tarkottaisi
ainoastaan leipää!… Vaan minä sanon: Muista aina, Martva, että ne
sanat tarkottavat iloakin ja onnea ja juomaa… vaatteitakin…"
— "Nyt uskon, että sinä puhut totta… Oi, miten rohkeana, useasti
minäkin olen kiusannut jo Häntä rukoillen Häneltä valmista vain
aina!… Hän varmaankin on suuttunut jo minuun…"
— "En tiedä mitä tehdä… Minä pelkään… Enhän minä, raukka, ole
suuri Jeesus… Oi! eivät Hänen työnsä minulle sovi."
ebookmasss.com