100% found this document useful (1 vote)
9 views

Introducing Functional Programming Using C#: Leveraging a New Perspective for OOP Developers 1st Edition Vaskaran Sarcar download

The document promotes the book 'Introducing Functional Programming Using C#' by Vaskaran Sarcar, which provides insights into functional programming for object-oriented developers. It includes links to download the book and other related resources on ebookmass.com. The book covers various aspects of functional programming, including immutability, function composition, and functional patterns.

Uploaded by

annypojota
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
9 views

Introducing Functional Programming Using C#: Leveraging a New Perspective for OOP Developers 1st Edition Vaskaran Sarcar download

The document promotes the book 'Introducing Functional Programming Using C#' by Vaskaran Sarcar, which provides insights into functional programming for object-oriented developers. It includes links to download the book and other related resources on ebookmass.com. The book covers various aspects of functional programming, including immutability, function composition, and functional patterns.

Uploaded by

annypojota
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 83

Download the full version and explore a variety of ebooks

or textbooks at https://ebookmass.com

Introducing Functional Programming Using C#:


Leveraging a New Perspective for OOP Developers
1st Edition Vaskaran Sarcar

_____ Tap the link below to start your download _____

https://ebookmass.com/product/introducing-functional-
programming-using-c-leveraging-a-new-perspective-for-oop-
developers-1st-edition-vaskaran-sarcar/

Find ebooks or textbooks at ebookmass.com today!


Here are some recommended products for you. Click the link to
download, or explore more at ebookmass.com

Introducing Functional Programming Using C#: Leveraging a


New Perspective for OOP Developers 1st Edition Vaskaran
Sarcar
https://ebookmass.com/product/introducing-functional-programming-
using-c-leveraging-a-new-perspective-for-oop-developers-1st-edition-
vaskaran-sarcar/

Introducing ReScript: Functional Programming for Web


Applications 1st Edition Danny Yang

https://ebookmass.com/product/introducing-rescript-functional-
programming-for-web-applications-1st-edition-danny-yang/

Simple and Efficient Programming with C#: Skills to Build


Applications with Visual Studio and .NET 2nd Edition
Vaskaran Sarcar
https://ebookmass.com/product/simple-and-efficient-programming-with-c-
skills-to-build-applications-with-visual-studio-and-net-2nd-edition-
vaskaran-sarcar/

Simple and Efficient Programming with C# : Skills to Build


Applications with Visual Studio and .NET 2nd Edition
Vaskaran Sarcar
https://ebookmass.com/product/simple-and-efficient-programming-with-c-
skills-to-build-applications-with-visual-studio-and-net-2nd-edition-
vaskaran-sarcar-2/
Modern C++ for Absolute Beginners: A Friendly Introduction
to the C++ Programming Language and C++11 to C++23
Standards, 2nd Edition Slobodan Dmitrovi■
https://ebookmass.com/product/modern-c-for-absolute-beginners-a-
friendly-introduction-to-the-c-programming-language-
and-c11-to-c23-standards-2nd-edition-slobodan-dmitrovic/

Options and Derivatives Programming in C++23: Algorithms


and Programming Techniques for the Financial Industry, 3rd
Edition Carlos Oliveira
https://ebookmass.com/product/options-and-derivatives-programming-
in-c23-algorithms-and-programming-techniques-for-the-financial-
industry-3rd-edition-carlos-oliveira/

Programming: Principles and Practice Using C++ , Second


Edition Stroustrup

https://ebookmass.com/product/programming-principles-and-practice-
using-c-second-edition-stroustrup/

Programming: Principles and Practice Using C++ 2nd


Edition, (Ebook PDF)

https://ebookmass.com/product/programming-principles-and-practice-
using-c-2nd-edition-ebook-pdf/

Programming for Absolute Beginners: Using the JavaScript


Programming Language 1st Edition Jonathan Bartlett

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

ISBN-13 (pbk): 978-1-4842-9696-7 ISBN-13 (electronic): 978-1-4842-9697-4


https://doi.org/10.1007/978-1-4842-9697-4

Copyright © 2023 by Vaskaran Sarcar


This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the
material is concerned, specifically, the rights of translation, reprinting, reuse of illustrations, recitation,
broadcasting, reproduction on microfilms or in any other physical way, and transmission or information
storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now
known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with
every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an
editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the
trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not
identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to
proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of publication,
neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or
omissions that may be made. The publisher makes no warranty, express or implied, with respect to the
material contained herein.
Managing Director, Apress Media LLC: Welmoed Spahr
Acquisitions Editor: Smriti Srivastava
Development Editor: Laura Berendson
Editorial Project Manager: Mark Powers
Cover designed by eStudioCalamar
Cover image by BoliviaInteligente on Unsplash (www.unsplash.com)
Distributed to the book trade worldwide by Apress Media, LLC, 1 New York Plaza, New York, NY 10004,
U.S.A. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail orders-ny@springer-sbm.com, or visit www.
springeronline.com. Apress Media, LLC is a California LLC and the sole member (owner) is Springer Science
+ Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc is a Delaware corporation.
For information on translations, please e-mail booktranslations@springernature.com; for reprint, paperback,
or audio rights, please e-mail bookpermissions@springernature.com.
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and
licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales
web page at www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this book is available to readers
on GitHub (https://github.com/Apress). For more detailed information, please visit https://www.apress.com/
gp/services/source-code.
Paper in this product is recyclable
This book is dedicated to all those developers who want to
improve their applications and do not give up easily.
Table of Contents
About the Author����������������������������������������������������������������������������������������������������� xi

About the Technical Reviewers����������������������������������������������������������������������������� xiii


Acknowledgments���������������������������������������������������������������������������������������������������xv

Introduction�����������������������������������������������������������������������������������������������������������xvii

Part I: Getting Familiar with Functional Programming����������������������������������� 1


Chapter 1: Functional Programming Overview��������������������������������������������������������� 3
C# Supports Multiple Paradigms�������������������������������������������������������������������������������������������������� 3
Functions and Methods Are Equivalent in C#�������������������������������������������������������������������������� 4
Important Characteristics of FP���������������������������������������������������������������������������������������������������� 5
FP Treats Functions as First-Class Citizens����������������������������������������������������������������������������� 6
FP Prefers Immutability����������������������������������������������������������������������������������������������������������� 8
FP Prefers Pure Functions����������������������������������������������������������������������������������������������������� 11
FP Follows a Declarative Style���������������������������������������������������������������������������������������������� 18
FP vs. OOP����������������������������������������������������������������������������������������������������������������������������������� 24
FP Benefits���������������������������������������������������������������������������������������������������������������������������������� 25
Exercises������������������������������������������������������������������������������������������������������������������������������������� 26
Summary������������������������������������������������������������������������������������������������������������������������������������ 28
Solutions to Exercises����������������������������������������������������������������������������������������������������������������� 28

v
Table of Contents

Chapter 2: Understanding Functions���������������������������������������������������������������������� 33


Mathematical Background of Functions������������������������������������������������������������������������������������� 33
Mathematical Functions vs. C# Functions���������������������������������������������������������������������������������� 35
Representing Functions in C#����������������������������������������������������������������������������������������������������� 35
Using Static Methods������������������������������������������������������������������������������������������������������������ 35
Using Delegates and Lambdas���������������������������������������������������������������������������������������������� 39
Using a Dictionary����������������������������������������������������������������������������������������������������������������� 42
Built-in Delegates Are Important������������������������������������������������������������������������������������������������� 45
Higher-Order Function����������������������������������������������������������������������������������������������������������������� 46
Custom HOF��������������������������������������������������������������������������������������������������������������������������� 46
Built-in HOF��������������������������������������������������������������������������������������������������������������������������� 48
First-Order Function�������������������������������������������������������������������������������������������������������������������� 49
Refactoring Impure Functions����������������������������������������������������������������������������������������������������� 49
Program with Impurities�������������������������������������������������������������������������������������������������������� 50
Removing Impurities�������������������������������������������������������������������������������������������������������������� 51
Exercises������������������������������������������������������������������������������������������������������������������������������������� 53
Summary������������������������������������������������������������������������������������������������������������������������������������ 54
Solutions to Exercises����������������������������������������������������������������������������������������������������������������� 55

Chapter 3: Understanding Immutability����������������������������������������������������������������� 59


What Is Immutability?����������������������������������������������������������������������������������������������������������������� 59
Immutable Objects in .NET���������������������������������������������������������������������������������������������������� 59
Reviewing Mutable Types����������������������������������������������������������������������������������������������������������� 61
Programming with a Mutable Type���������������������������������������������������������������������������������������� 61
The Path Toward Immutability����������������������������������������������������������������������������������������������������� 62
Achieving External Immutability�������������������������������������������������������������������������������������������� 62
Enforcing Internal Immutability��������������������������������������������������������������������������������������������� 65
Better Code Using Modern Features�������������������������������������������������������������������������������������� 68
More on Immutability������������������������������������������������������������������������������������������������������������������ 72
Understanding Shallow Immutability������������������������������������������������������������������������������������� 73
Searching for a Solution�������������������������������������������������������������������������������������������������������� 77

vi
Table of Contents

Making a Better Solution������������������������������������������������������������������������������������������������������� 80


Implementing Popsicle Immutability������������������������������������������������������������������������������������� 83
Exercises������������������������������������������������������������������������������������������������������������������������������������� 87
Summary������������������������������������������������������������������������������������������������������������������������������������ 88
Solutions to Exercises����������������������������������������������������������������������������������������������������������������� 89

Part II: Harnessing the Power of Functional Programming�������������������������� 93


Chapter 4: Composing Functions Using Pipelining������������������������������������������������� 95
Overview������������������������������������������������������������������������������������������������������������������������������������� 95
Coding Functional Composition��������������������������������������������������������������������������������������������� 95
Importance of Chaining Functions���������������������������������������������������������������������������������������������� 99
Program Without Chaining Functions������������������������������������������������������������������������������������ 99
Refactoring Using Chaining Functions�������������������������������������������������������������������������������� 102
Applying Composition��������������������������������������������������������������������������������������������������������������� 106
Using Pipelining������������������������������������������������������������������������������������������������������������������� 106
Using HOFs�������������������������������������������������������������������������������������������������������������������������� 109
Exercises����������������������������������������������������������������������������������������������������������������������������������� 112
Summary���������������������������������������������������������������������������������������������������������������������������������� 113
Solutions to Exercises��������������������������������������������������������������������������������������������������������������� 113

Chapter 5: Composing Functions Using Currying������������������������������������������������� 119


Overview of Currying���������������������������������������������������������������������������������������������������������������� 119
Program Without Currying��������������������������������������������������������������������������������������������������� 120
Using the Concept of Currying��������������������������������������������������������������������������������������������� 121
Using External NuGet Packages������������������������������������������������������������������������������������������������ 129
Using Curryfy����������������������������������������������������������������������������������������������������������������������� 130
Exercises����������������������������������������������������������������������������������������������������������������������������������� 136
Summary���������������������������������������������������������������������������������������������������������������������������������� 138
Solutions to Exercises��������������������������������������������������������������������������������������������������������������� 139

vii
Table of Contents

Chapter 6: Handling Temporal Coupling��������������������������������������������������������������� 145


Temporal Coupling Overview���������������������������������������������������������������������������������������������������� 146
How Does This Happen?������������������������������������������������������������������������������������������������������ 146
Recognizing the Problem���������������������������������������������������������������������������������������������������������� 146
A Program That Suffers from Temporal Coupling���������������������������������������������������������������� 147
Removing the Effect������������������������������������������������������������������������������������������������������������������ 155
A Better Program����������������������������������������������������������������������������������������������������������������� 156
Exercises����������������������������������������������������������������������������������������������������������������������������������� 165
Summary���������������������������������������������������������������������������������������������������������������������������������� 167
Solutions to Exercises��������������������������������������������������������������������������������������������������������������� 167

Chapter 7: Functional Patterns����������������������������������������������������������������������������� 171


Map Pattern������������������������������������������������������������������������������������������������������������������������������ 172
Understanding the Problem������������������������������������������������������������������������������������������������� 173
Initial Solution���������������������������������������������������������������������������������������������������������������������� 173
Better Solution��������������������������������������������������������������������������������������������������������������������� 177
Concise Solution������������������������������������������������������������������������������������������������������������������ 178
Select As Map���������������������������������������������������������������������������������������������������������������������� 182
Introducing Functors����������������������������������������������������������������������������������������������������������� 186
Conclusion��������������������������������������������������������������������������������������������������������������������������� 186
Bind Pattern������������������������������������������������������������������������������������������������������������������������������ 187
Understanding the Problem������������������������������������������������������������������������������������������������� 187
Initial Solution���������������������������������������������������������������������������������������������������������������������� 188
FP-Based Solution��������������������������������������������������������������������������������������������������������������� 189
SelectMany As Bind������������������������������������������������������������������������������������������������������������� 191
What About Monads?����������������������������������������������������������������������������������������������������������� 192
Conclusion��������������������������������������������������������������������������������������������������������������������������� 193
Filter Pattern����������������������������������������������������������������������������������������������������������������������������� 194
Understanding the Problem������������������������������������������������������������������������������������������������� 194
Initial Solution���������������������������������������������������������������������������������������������������������������������� 195
Where As Filter�������������������������������������������������������������������������������������������������������������������� 198

viii
Table of Contents

Fold Pattern������������������������������������������������������������������������������������������������������������������������������ 199


Understanding the Problem������������������������������������������������������������������������������������������������� 202
Solutions Using Built-in Functions�������������������������������������������������������������������������������������� 202
Conclusion��������������������������������������������������������������������������������������������������������������������������� 205
Revisiting ForEach�������������������������������������������������������������������������������������������������������������������� 207
Exercises����������������������������������������������������������������������������������������������������������������������������������� 208
Summary���������������������������������������������������������������������������������������������������������������������������������� 210
Solutions to Exercises��������������������������������������������������������������������������������������������������������������� 210

Chapter 8: Exception Handling����������������������������������������������������������������������������� 215


Reviewing Exception Handling in OOP�������������������������������������������������������������������������������������� 215
Imperative Style of Programming���������������������������������������������������������������������������������������� 217
Exception Handling in FP���������������������������������������������������������������������������������������������������������� 218
Using language-ext������������������������������������������������������������������������������������������������������������� 219
Introducing the Either Type�������������������������������������������������������������������������������������������������� 219
Handling a Single Exception������������������������������������������������������������������������������������������������ 224
Handling Multiple Exceptions���������������������������������������������������������������������������������������������� 226
Chaining Exceptions������������������������������������������������������������������������������������������������������������ 230
Handling Null Values����������������������������������������������������������������������������������������������������������������� 238
Introducing the Option Type������������������������������������������������������������������������������������������������� 239
Exercises����������������������������������������������������������������������������������������������������������������������������������� 248
Summary���������������������������������������������������������������������������������������������������������������������������������� 251
Solutions to Exercises��������������������������������������������������������������������������������������������������������������� 252

Chapter 9: Miscellaneous Topics�������������������������������������������������������������������������� 257


Helpful Features for FP������������������������������������������������������������������������������������������������������������� 257
Delegates and Lambdas������������������������������������������������������������������������������������������������������ 257
Anonymous Methods����������������������������������������������������������������������������������������������������������� 258
Extension Methods and LINQ����������������������������������������������������������������������������������������������� 259
Type Inference��������������������������������������������������������������������������������������������������������������������� 263
Importing Static Members��������������������������������������������������������������������������������������������������� 263

ix
Table of Contents

Immutability Features���������������������������������������������������������������������������������������������������������� 264


Expression-Bodied Members���������������������������������������������������������������������������������������������� 265
Local Functions������������������������������������������������������������������������������������������������������������������� 268
Tuples���������������������������������������������������������������������������������������������������������������������������������� 270
Pattern Matching����������������������������������������������������������������������������������������������������������������� 272
Revisiting Option<T>���������������������������������������������������������������������������������������������������������������� 275
Bind Function���������������������������������������������������������������������������������������������������������������������� 277
Return Function������������������������������������������������������������������������������������������������������������������� 279
Introducing Monads������������������������������������������������������������������������������������������������������������������ 280
Definition����������������������������������������������������������������������������������������������������������������������������� 280
Mathematical Background�������������������������������������������������������������������������������������������������� 281
Monad Laws������������������������������������������������������������������������������������������������������������������������ 281
Chaining Multi-argument Functions����������������������������������������������������������������������������������������� 283
Final Suggestions���������������������������������������������������������������������������������������������������������������������� 285
Command Query Separation������������������������������������������������������������������������������������������������ 285
Learn Design Patterns and Anti-Patterns���������������������������������������������������������������������������� 285
Don’t Let Failures Stop You�������������������������������������������������������������������������������������������������� 286
How Much Functional Code Do I Need?������������������������������������������������������������������������������ 287
Applications of FP��������������������������������������������������������������������������������������������������������������������� 287
The Road Ahead������������������������������������������������������������������������������������������������������������������������ 287
Exercises����������������������������������������������������������������������������������������������������������������������������������� 288
Summary���������������������������������������������������������������������������������������������������������������������������������� 290
Solutions to Exercises��������������������������������������������������������������������������������������������������������������� 291

Appendix: Recommended Resources������������������������������������������������������������������� 295

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/.

Shekhar Kumar Maravi is a lead engineer in design and


development, whose main interests are programming
languages, algorithms, and data structures. He obtained his
master’s degree in computer science and engineering from
the Indian Institute of Technology, Bombay (India). After
graduation, he joined Hewlett-­Packard’s R&D Hub in India
to work on printer firmware. Currently he is a technical lead
engineer for automated pathology lab diagnostic devices in
the Siemens Healthcare R&D division. He can be reached
by email at shekhar.maravi@gmail.com or via LinkedIn at
https://www.linkedin.com/in/shekharmaravi.

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.

• Shekhar Kumar Maravi: Shekhar was another technical reviewer for


this book. He has been reviewing my books since 2015. Whenever I
am in need, he provides me with support. Thank you one more time.

• Smriti, Laura, and Mark: Thanks to each of you for giving me


another opportunity to work with you and Apress.

• 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.

How Is This Book Organized?


The book has two major parts, which are as follows:

• 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

Who Is This Book For?


In short, read this book if you answer “yes” to the following questions:

• Are you familiar with .NET, C#, and basic object-oriented concepts
such as polymorphism, inheritance, abstraction, and encapsulation?

• Are you familiar with some of the advanced concepts in C# such as


delegates, lambda expressions, and generics?
• Do you know how to set up your coding environment?

• Do you want to develop your functional programming skills?

• 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:

• Are you looking for a C# tutorial or reference book?

• Are you not ready to experiment with FP with a programming


language that was primarily developed for OOP?

• Do you despise Windows, Visual Studio, or .NET?

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.

• Nowadays the C# language version is automatically selected based


on your project’s target framework(s) so that you can always get the
highest compatible version by default. In the latest versions, Visual
Studio doesn’t allow the UI to change the value, but you can change it
by editing the .csproj file.

xx
Introduction

• As per a new rule, C# 11 is supported only on .NET 7 and newer


versions. C# 10 is supported only on .NET 6 and newer versions. C# 9
is supported only on .NET 5 and newer versions. C# 8.0 is supported
only on .NET Core 3.x and newer versions. If you are interested in the
C# language versioning, you can visit https://docs.microsoft
.com/en-us/dotnet/csharp/language-reference
/configure-language-version.

• 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.

Guidelines for Using This Book


Here are some suggestions so you can use the book more effectively:

• 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.

• I organized the chapters in an order that can help grow your


functional thinking with each chapter. Therefore, I recommend
reading the chapters sequentially.

• 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.

Conventions Used in This Book


In many places, I point you to Microsoft’s documentation. Why? As the creator of C#,
Microsoft is the primary authority on each feature.

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):

Understanding Mutability and Immutability.


Name: Sam, ID:1
The emp1's hashcode:43942917
The temp's hashcode:43942917
Name: Sam, ID:2
The emp1's hashcode:59941933
The temp's hashcode:43942917

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

Getting Familiar with


Functional Programming
Part I consists of three chapters. It starts with an overview of functional programming
(FP). Then it discusses functions and immutability in depth. Specifically, Part I covers
the following topics:
• Chapter 1 provides a quick overview of functional programming and
describes the important characteristics of FP. This chapter compares
FP and object-oriented programming (OOP) and also points out the
key benefits of using FP.
• Functions are the building blocks for FP. Chapter 2 provides a
detailed discussion of functions and covers first-order and higher-­
order functions. This chapter also shows a simple technique for
refactoring impure functions into pure functions and making your
code more “functional.”
• Immutability is another important characteristic of FP. Chapter 3
discusses this topic in depth with examples of external, internal,
shallow, and popsicle immutability using features available in C#.

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.

C# Supports Multiple Paradigms


Different programming languages usually target different coding styles/paradigms.
But when programming language developers introduce new features to make a language
richer, the features may not follow the original programming style; instead, languages
can support multiple programming paradigms. As a result, over time these computer
languages become hybrid in nature. The associated benefit is obvious: you can make
an application by choosing the approach that suits your needs best (or even mixing the
approaches). For example, an object-oriented programming (OOP) developer may use
the functional style of coding in some code segments to reap some particular benefit.

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

C# and F# are .NET programming languages. F# is primarily a functional language,


but it supports the .NET object model. On the other hand, C# is primarily object-
oriented, but it supports several functional features. Particularly, in the latest versions,
you’ll see plenty of support for functional programming. Let’s see what Microsoft
says about this (see https://learn.microsoft.com/en-us/dotnet/standard/linq/
concepts-terminology-functional-transformation):

Historically, general-purpose functional programming languages, such


as ML, Scheme, Haskell, and F#, have been primarily of interest to the
academic community. Although it has always been possible to write pure
functional transformations in C# and Visual Basic, the difficulty of doing so
has not made it an attractive option to most programmers. In recent
versions of these languages, however, new language constructs such as
lambda expressions and type inference make functional programming
much easier and more productive.

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.

Functions and Methods Are Equivalent in C#


Like any other OOP developer, you may like using the term method instead of
function. In C#, you typically place methods inside a class because they do not exist
independently. Since C# primarily supports OOP, you see this kind of design often.
It should not be a surprise to you that functions are the building blocks for FP.
The online link https://learn.microsoft.com/en-us/dotnet/standard/linq/
refactor-pure-functions says the following:

However, in C#, functions are called methods.

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 treats functions as first-class citizens.

• It prefers immutability.

• It prefers pure functions.

• It follows declarative programming.

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

FP Treats Functions as First-Class Citizens


FP treats functions as first-class citizens. What does this mean? This means you can use
them like any other type. For example, you can assign a function to a variable, pass it as
an argument to another function, or use it as a return type. It is possible to store them
in data structures too. When someone says that a programming language supports
first-class functions, you can assume that the programming language supports these
concepts. So, you can think of first-class functions as a programming language feature.
Since we are trying to adopt functional programming, the following questions may
come to your mind:

• What is a function type in C#?

• Does C# have first-class functions?

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:

Func<int, int> doubleMaker = x => x * 2;

This code says the following:

• I have a function that takes an integer, multiplies it with 2, and


returns the result.

• I have assigned this function to the variable doubleMaker.

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.

using static System.Console;

int temp = 5;
Func<int, int> doubleMaker = x => x * 2;
int result = Container.GetResult(doubleMaker,temp);
WriteLine(result);

static class Container


{
    public static int GetResult(Func<int,int> f, int x)
    {
        return f(x);
    }
}

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:

• You can assign a function to a variable.

• You can pass a function as an argument to another function.


As you progress more with learning FP, it will be natural for you to use functions
as return types or store them in a data structure. So, we can conclude that C# indeed
supports first-class functions.

7
Chapter 1 Functional Programming Overview

FP Prefers Immutability


Immutability is a design choice, and it is one of the fundamental principles of FP. In this
context, I’d like to quote Microsoft again. The online link https://learn.microsoft.
com/en-us/archive/msdn-magazine/2010/april/fsharp-basics-an-introduction-
to-functional-programming-for-net-developers says the following:

Imperative programming emphasizes the use of mutable variables whereas


functional programming uses immutable values.
Chapter 3 of this book discusses many aspects of immutability. In the .NET world,
it means that once you initialize (or create) a type, you should not change its internal
state at a later stage. Immutability is a big topic. For now, let’s have a quick review.

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:

using static System.Console;

List<string> names = new() { "Sam", "Bob" };


WriteLine("The list includes the following names:");
names.ForEach(x=> WriteLine(x));

// Removing existing names


names.Clear();
// Adding two new names
names.Add("Kate");
names.Add("Jack");

WriteLine("\nThe list includes the following names:");


names.ForEach(x => WriteLine(x));

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.

The list includes the following names:


Sam
Bob

The list includes the following names:


Kate
Jack

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?

Immutability prevents nasty bugs from implicit dependencies, destructive updates,


and state mutations. These are aligned with FP’s goal. Immutable types are thread-safe;
therefore, in a multithreaded environment, they make your programming life easy.
Shortly, you’ll learn about pure functions and side effects. Then you’ll understand that
these immutable types can help you avoid side effects too. In Chapter 6, you’ll see that
immutable types are also useful to avoid temporal coupling. There are many more benefits;
once you finish this book, you’ll be able to find those benefits in other areas as well.

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:

int random = new Random().Next(0, 2);


string? newName = random > 0 ? "Jack": null;
// Adding a new name
names.Add(newName);

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):

using static System.Console;

WriteLine("Analyzing destructive updates.");

List<string> names = new() { "Sam", "Bob" };


WriteLine("The list includes the following:");
names.ForEach(x => WriteLine($"Name: {x},length:{x.Length}"));

int random = new Random().Next(0, 2);


string? newName = random > 0 ? "Jack": null;
// Adding a new name
names.Add(newName);
WriteLine("\nThe list includes the following names:");
names.ForEach(x => WriteLine($"Name: {x},length:{x.Length}"));

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:

Analyzing destructive updates.


The list includes the following:
Name: Sam,length:3
Name: Kate,length:4

The list includes the following names:


Name: Sam,length:3
Name: Kate,length:4
Name: Jack,length:4

But based on the generated random number (when it is 0), this program can throw
the following runtime exception:

System.NullReferenceException: 'Object reference not set to an instance of


an object.'
x was null.

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.

FP Prefers Pure Functions


FP wants you to use pure functions as much as possible. Microsoft (see https://learn.
microsoft.com/en-us/dotnet/standard/linq/refactor-pure-functions) echoes this
by saying the following:

The common nomenclature in functional programming is that you refactor


programs using pure functions.

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:

using static System.Console;

WriteLine(AddFiveTo(2));
WriteLine(GetRandomNumber(2));

static int AddFiveTo(int input)


{
    return input + 5;
}
static int GetRandomNumber(int input)
{
    Random random = new();
    return random.Next(input, input + 5);
}

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.

Discussion of Side Effects


Let’s discuss side effects. Look at the following possibilities:

• Case 1: Your function keeps modifying a static variable.

• Case 2: You modify the function argument by passing a parameter as


a reference.

• Case 3: Your function raises an exception for certain cases.

• 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

        int random = new Random().Next(0,2);


        return a / random;
    }
}

The first problem is obvious: you cannot predict the result in advance. For example,
the following line:

int result = Sample.GetResult(6);

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.

Functions with I/O


It should not be a surprise that a meaningful program often needs to accept user input
and display the output. So, you may be wondering, if a function displays the output of
a program, is it a side effect? Let’s analyze this. If a function asks a user to pass a URL to
display a webpage, the result can vary when the internet connection becomes unstable
or the server is down. As a result, the same function can potentially produce different
results. In fact, thinking about the output can make you even more uncomfortable.
Consider the case when a function queries a user by outputting text to the console
something like the following:

   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

Are Side Effects Bad?


Up until now we have been discussing function purity following the formal definition.
Now the question is, are impure functions acceptable? Here are my thoughts on them:

• We make assumptions about purity to some extent. This is because


any function can fail because of some factors that are beyond our
control. Consider the case of the “out of memory” error when your
code did not cause the error, but it came from someone else’s code,
which was executing in a parallel environment. Or, consider the case
when the operating system (OS) itself crashes. If you consider cases
like this, no function is 100 percent pure, and this is the sad truth! So,
when we talk about side effects, we ignore the factors that are beyond
our control.

• 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:

• Any side effect indicates a visible “state change” of a program.

• A pure function is “pure” to some extent. We cannot avoid all possible


circumstances. For example, during an execution of a C# function, an exception
can be thrown because of various factors. Typical examples include insufficient
memory or any other operating system errors.

• 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.

1.5 Why do FP developers try to avoid side effects?


Side effects can change program states. This characteristic can compromise the
correctness of the code. In addition, a method that has side effects does not depend
entirely on program inputs. Because of this, it is difficult to predict the program’s

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.

FP Follows a Declarative Style


Functional programming follows the declarative style of coding. What does this mean?
A declarative style focuses on “What do we want?” instead of saying something like
“Do this step, then do that step to get the result.” When you mention a step-by-step
approach to solving a problem, the approach is imperative, not declarative. So, the
imperative style of programming describes how to solve the problem. The following
statements will make the concept clearer to you:

• Imperative programming approach: Traverse the employee


list sequentially. If the employee’s age is 30 or more, show the
employee’s detail.

• Declarative (functional) programming approach: From a given list,


display the details of the employees who are 30 years or older.

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):

using static System.Console;

WriteLine("Using an imperative style of coding.");


List<int> numbers = new() { 10, 20, 30, 40, 50 };
// Imperative style
WriteLine("The list includes the following:");
foreach (int number in numbers)
{
    Write(number + "\t");
}
18
Chapter 1 Functional Programming Overview

WriteLine("\nAges that are more than 30:");


foreach (int number in numbers)
{
    if (number > 30)
    {
        Write(number + "\t");
    }
}

Output
This program produces the following output:

Using an imperative style of coding.


The list includes the following:
10      20      30      40      50
Ages that are more than 30:
40      50

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):

using static System.Console;

WriteLine("Using the declarative style of coding.");


List<int> numbers = new() { 10, 20, 30, 40, 50 };
WriteLine("The list includes the following:");
numbers.ForEach(x => Write(x + "\t"));
WriteLine("\nAges that are more than 30:");

19
Chapter 1 Functional Programming Overview

numbers.Where(x => x > 30)


    .Select(x => x)
    .ToList()
    .ForEach(x => Write(x + "\t"));

Output
It should be no surprise that you see an equivalent output (that you saw in
Demonstration 5):

Using the declarative style of coding.


The list includes the following:
10      20      30      40      50
Ages that are more than 30:
40      50

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++;
   }

   if (random2 >= 13)


   {
       flag+=2;
   }
   WriteLine($"The flag is:{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:

using static System.Console;


#region imperative
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}");
if (random1 % 2 == 0)
{
    flag++;
}

if (random2 >= 13)


{
    flag += 2;
}
WriteLine($"The flag is: {flag}");
#endregion

#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

FP vs. OOP


Each coding style has associated pros and cons. This book uses C# as the programming
language, which primarily supports OOP. But as mentioned, C# also supports FP. So, you
may like to know some of the differences between these approaches. Once you learn
about FP principles, you’ll understand that these principles are orthogonal to each other.
Microsoft (https://learn.microsoft.com/en-us/dotnet/standard/linq/functional-
vs-imperative-programming) says the following:

Functional programming is a form of declarative programming. In con-


trast, most mainstream languages, including object-oriented programming
(OOP) languages such as C#, Visual Basic, C++, and Java, were designed to
primarily support imperative (procedural) programming.

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.

• In a multithread environment, you can write better code that can


prevent traditional problems such as lost updates and deadlocks.
Let me remind you about a typical scenario: in a multithreaded
application, avoiding race conditions is a big concern for us. Often,
you introduce locks to avoid them. But these locks are expensive.
Now the question is, how can you avoid them? One probable solution
is to follow the functional style of coding in certain code segments.
Since FP uses immutable types, you can write lock-free code.

• FP helps you write independent code segments. These are essential


when you want to introduce parallelism.

• Finally, FP shows you a new perspective on development. If you are


aware of other paradigms such as OOP, you can combine them with
FP to make better applications.

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;}

    public static void ChangeStatus()


    {
        OpsDone = !OpsDone;
    }

    public static int FindDifference(int a, int b)


    {
        return Math.Abs(a - b);
    }
    public static int GetSquare(int x)
    {
        return x * x;
    }
    public static int GetCube(int x)
    {
        OpsDone = true;
        return x * x * x;
    }
26
Other documents randomly have
different content
et aikanansa pois kitke sitä taikka tukahduta…"

Martva hätäytyi… Hän muisti Oolavia… Lemmen suru leimahti


tuleksi… Sitä tulta sytytti Perkeleen palava katse… Hän aavisti
Oolavin tuottavan hänelle tuskaa, eikä tajunnut miten tuo tuotti, ei
mitä on se tuska… Sydän vavahti… Hän huudahti avuttomana:

— "Oi miksi minua noin pelottelet?…"

Lemmettäret surivat… Ei pyörähtänyt rukin runokiiju… Lumoavana,


kavalana selitti Perkele kiusattavalle:

— "Paras on kuulla totuus aikanansa… Huomenna on se ehkä liian


myöhä… Jos aikanansa tuskan idut poltat pois elämästä itse
elämällä, niin silloin aina kuolemaasi asti hymyilee onni aina
kukissaan… Ja silloin koko sinun elämäsi kylvää sinulle armaimpia
antimiaan: iloa, kukkia ja säveleitä, rakkautta, tanssia ja muuta… Siis
pidä huoli, ettei neitsyt-aika hyödyttä pääse käsistäsi pois!…"

Hän soitteli Martvan mieltä katseillansa ja äänellänsä… Hän loihti


hänen sieluunsa tuskan ja murheen kangastukset… Hätäytyneenä,
katse rukoilevana, huudahti jo Martva hänelle:

— "En minä kaipaa koskaan maailmassa iloa, tanssia ja säveleitä…


Vaan tuskaa, josta puhut, kyllä pelkään ja tahtoisin sen kauvas
karkottaa… En itsestäni mitään välittäisi, vaan tuskahan on raskas
muiden tähden: Suurimman osan saavat siitä toiset… Sen vuoksi
pelkään tuskaa päivät, yöt…"

Ohdakkeen kukka iloitsi ja kasvoi siementänsä… Suuri kiusaus


jatkui… Yhä lumoavampana puhui Perkele. Hän vakuutti hartaana,
kiehtovana:
— "Se ajatuksesi on suuri, jalo… On oikein että muista pidät
huolta… Vaan muista: kerran tulee tuskan hetki ja silloin saavat
sinun rakkaimpasi osansa kantaa sinun tuskistasi… On totta: tuska
painaa ystävää raskaammin kuin sen tuskan tuntijaa."

Kuin arka lintunen katseli Martva suurta henkeä… Hän hätäytyi ja


huudahteli suurten lumojen alaisena:

— "Voi miksi toisten, viatonten, täytyy minun tuskistani aina osa


saada!… Ah, jos ne tuskat heidän tähtensä voisin nyt kiertää, salata
tai karkottaa!…"

Luonto suri… Kukka koreili kastekyynelissänsä. Tuskankukkaset


hymyilivät kauneina… Ne olivat muuntuneet lemmenkukkasista…
Kylmänä kysyi Perkele:

— "Ja miksi et voi kiertää tuskiasi?…"

Kaikki suri, kaikki itki… Perkele loihti tuskantulet kiusattavan


nähtäviksi… Neidon voimat raukesivat… Hän vastasi avuttomana:

— "Miksi en voi kiertää tuskiani!… Mitenkä vastaan siihen… ah, en


osaa!… En, raukka, tiedä mitään pakopaikkaa, mihinkä silloin voisin
piiloutua, kun tuska ehkä saapuu minun luokseni… On kaikki outoa
ja hämärää!…"

Suuret lumot leijailivat Martvan päällä… Mieli värisi tuskantulelle.


Perkele puhui hänelle osan-otolla:

— "Sinua säälin sekä avun annan: Saat tästä tämän kulta-


avaimeni… Kun uhkaa tuska taikka epätoivo, niin avaa silloin tällä
avaimella se portti, joka Harhasaareen vie!"
Lemmettäret pidättivät henkeänsä… Luonto värisi odotuksesta… Ei
tiennyt mikään, kestäisikö ihmishenki kiusauksensa… Mutta se kesti:
Peljästyneenä, hätäytyneenä huudahti Martva:

— "En milloinkaan!… En koskaan elämässä… en tuskantulessakaan


mene Harhasaareen!… On Gabriel jo siitä varottanut… Hän kielsi
Harhasaareen menemästä!…"

Luonto huokasi… Kukka karisti kyyneleensä… Lemmettäret


pyöräyttivät runorukkinsa hyrisemään ilosta, kun oli voittanut
ihmishenki… Kiukkunsa salaten lausui Perkele, hämmästyneeksi
tekeytyen:

— "Onko totta mitä äsken sanoit!… Nyt, Martva, olet varmaan


erehtynyt? En usko, että Harhasaarta olisi hän kielletyksi voinut
valehdella… Näät, eihän Luoja ole raamatussaan moisesta
sanallakaan maininnut… Hyvän- ja pahantiedon puun Hän kielsi!… Ja
Harhasaarihan on aivan toista!… Kun sinne menet, niin saat silmin
nähdä taivaiset ihanuudet sekä onnen… Kas, siellä sulhasesi
odottaa…"

Hän katsoi kiusattavaan kavalana… Hän loihti hänen sieluunsa


outoja kuvia… Lumous ja tenho lähtivät hänestä… Martva tunsi sen
tenhon voiman. Hän hätäytyi ja selvisi vuoroon… Avuttomana seisoi
hän suurten voimien edessä. Kuin apua anoen vakuutti hän
Perkeleelle:

— "Ei Oolavini mene Harhasaareen… Hän lähti kotoansa tiedon


hakuun. Kun aika joutuu, palaa hän taas Litvaan. Hän silloin minulle
suuren ilon tuo…"

Kiehtovana, kavalana ja lumoavana tarttui Perkele siihen:


— "Kenties!… Kenties!… En tahdo sitä kieltää… Toki olisi syytä
pieni silmäys heittää myös Harhasaaren onnen kukkamaille… Kenties
jos siellä Oolavikin on…"

Hajanaisena, surullisena, mutta lumouksesta vapautuneena


huudahti siihen Martva:

— "Ei… ei… En usko moista, vaikka minulle sitä kuka vakuuttaisi…


Kun Harhasaari on kielletty, silloin ei mene sinne Oolavi, ei
koskaan…"

Luonto iloitsi… Perho leperteli kukkasessa… Lemmenrihmat


juoksivat taas puhtaina, runollisina… Harmistuneena yritti Perkele
uudestaan, vakuuttaen:

— "Tee ja usko mitä itse tahdot!… Toki uudistan nyt vielä


vakuutuksen: ei Harhasaarta ole kielletty koskaan… Jos astut
Harhasaareen, niin saat maistaa ikuisen, suuren, jumalaisen onnen…
Se saari on aivan täynnä hedelmiä: iloa, nautintoa, joka tukahduttaa
surusi: tuskan idun, sekä antaa onnen…"

Hänen äänensä huumasi kuin suloinen soitto. Hänen katseensa


kiehtoi kuin kaunis taika. Mutta Martva oli jo lumoista päässyt. Hän
vastasi voimistuneena:

— "Ei onni ole koskaan nautinnoissa, iloissa, eikä omien


toivonnassa… Korkein, jaloin mainen ihmisonni on hento, pieni,
kaunis korven kukka, joka ei koskaan menesty ja viihdy ilossa, eikä
elon hyörinässä… Se etsii rauhaisimman korvensilmän puhtaaksi
onnen paratiisiksensa… Ah hurskas nunnakin on onnellisin, kun saapi
olla yksin kammiossaan… Minulle ovat Litvan maat ja metsät se
korvensilmä, josta joka aamu ihanin onnenkukka puhkeaa… Miksi
silloin lähden suotta Harhasaareen!"

Hän oli voittanut kiusauksensa… Murheelliseksi tekeytyen lausui


Perkele hänelle:

— "Niin: avuksesi tulin ystävänä, vaan huomaan että minun


sanojani ja neuvojani nyt et uskokaan… Niin: ehkä vielä luulet
pettäjäksi!…"

Se koski Martvan mieleen. Anteeksi pyytäen, pahoilla mielin


keskeytti hän, huudahtaen:

— "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."

Taivaalla hymisi silloin ihanin enkelilaulu… Siellä iloittiin


ihmishengen voitosta. Ilkeytensä ja vihansa salaten jätti Perkele
Martvan. Lähtiessään hän lausui itseksensä kiukkuisena:

— "Hän lausui kuten Jeesus kerran: 'Mene pois, Saatana'… No


hyvä!… Minä menen pois hänen luotaan, mutta hänen elämäänsä en
silti toki käsistäni päästä… ja luoksensakin pian palaan taas."
Mutta Lemmensaareen laskeutui Herran rauha, kuin sunnuntainen
kirkko-ajan hartaus, joka kesäpäivän tyynenä laskeutuu rauhallisten
maiden yli ja peittää vedet, joilta on arkipäivän äänet lakanneet
kuulumasta, jättäen ne hengen rauhaisiksi asuinmaiksi, missä
äänettömyys hohtaa kukassansa, kuten tuonen rauha
haudantakaisessa kauniissa paratiisin hämärässä… Ja siihen suureen
rauhaan laskeutui taivaan korkeudesta kaunis parvi enkeleitä siellä
puhdasta Martvaa hyvän tielle ohjaamaan…

Tienviereltä uusia tuttuja tarttui.

Elämäntie vieri. Kulkija eteni sen mukana. Tienvarsi vilisi jo uusista


tutuista.

Kylmä, sakea pakkasen usva pimensi öistä ilmaa, peittäen taivaan


tulina palavat tähdet. Ainoastaan joku kirkkain niistä tuikutti sumun
läpi heikkona, sammuvana kipinänä. Eloton pakkanen pureksi
korvanlehtiä kirpeästi kuin tulikipinä.

Eräässä hotellin yksityishuoneessa oli koolla viisi nuorta miestä,


Oolavi niiden mukana. Toiset neljä olivat jonkunlaista alinta
muunnosta siitä joukosta, joka kulkee itse ottamallansa nimellä
jeunesse d'orée. Joukon johtavana henkenä oli roteva Yrjö Harteva.
Toisena merkkimiehenä pidettiin Veikko Horsmaa. Aatu Voima ja
Väinö Ilanne olivat vielä heidän johdettavinansa. Yrjö Hartevasta oli
tapa sanoa, että hän on ammatiltansa herrasmies.

Korttipeli oli käynnissä. Huone oli sakeanaan tupakansavua


täynnä. Sähkövalokin valaisi himmeähkösti sen läpi. Keskellä
huonetta oli pöytä, jonka ympärillä seurue istui korttia lyömässä.
Ryyppylasit ja pari puolilleen juotua pulloa, sekä poroastiat, jotka
olivat kukkuroillansa tuhkaa, paperossin tyviä ja sikarin pätkiä,
täydensivät pöydän ja koko huoneen ylen runotonta kuvaa.

— "Kuka sekaa kortit?" — kysyi Harteva, viskaten korttipakan


pöydälle ja rehentelevänä heittäytyen tuolin selkämää vastaan.

— "Tuo tänne! Se on minun vuoroni", — lausui siihen Oolavi ja


alkoi sekottaa kortteja. Hänen sitä tehdessänsä selitteli Harteva,
jatkaen keskustelua:

— "Sinä, Oolavi, olet kerrassaan erehdyksissä, aivan peukaloasi


myöten. Anarkia, täysi anarkia, on ainoata oikeaa vapaamielisyyttä.
Sillä katso nyt, mitä on vapaamielisyys josta puhut: Jos se sanoo,
että anarkia ei ole oikea ja rupeaa sitä ahdistamaan, eikö se silloin
ole ahdasmielinen ja vanhoillinen?"

— "Se nyt on taas toinen asia", — väitti Oolavi.

— "Sotke kortteja äläkä minun selvää meininkiäni!" — kiivastui


Harteva jatkaen: "Entä jos vapaamielisyys on oikeaa, eikö sen pidä
vapaamielisesti myöntää, että vanhoillisetkin saavat olla ja hallita
miten haluavat?"

Oolavi mietti asiaa ja myönteli:

— "Kyllähän se on niinkin… jos sinun ajatustasi käyttää…"

Harteva sytytti sikarin, puhalsi paksun savupilven suustansa ja


järkeili edelleen:
— "Jos vapaamielisyys ei vapaamielisesti myönnä kaikkien olevan
oikeassa, vaan ahdasmielisesti karkaa muita vastaan ja väittää
ainoastaan itsensä oikeassa olevan, senkö juuttaan vapaamielisyyttä
se sitten on!… Ahdasmielisyyttähän se on, joka on vielä niin
raukkamaista, että ei uskalla tunnustaa olevansa ahdasmielisyyttä!…
Mikä se on valttia?… Ruutu!… Nyt tuli tupen rapina!… Yksi valtti vain
ja sekin huono… Pieti tulee, vaan tulkoon… Hei, pojat!"

— "Hei!" hihkaisi Horsma.

— "Lyö päälle!" — kehotti Voima uljaana.

— "Lyön kyllä!… Hei!" — ylpeili tanakka Ilanne lyöden kortin


pöytään.

— "Minä kaadan."

— "Niinpäs tuli pieti, kuin ennustin," — rehenteli Harteva jatkaen:

— "Voiko siis mitään vapaamielisyyttä olla… muuta kuin anarkia?"

— "Kyllä se, juukeli, siltä tuntuu, kun oikein ajattelee", —


myönnytteli Oolavi. Harteva sai siitä pontta puheeseensa ja vannoi:

— "No johan sinä lopultakin saat järjen päästä kiinni!… Olenhan


minä sinulle vakuuttanut, että ei voi olla muuta kuin anarkia ja sitten
sen vastakohta vanhoillisuus eli ahdasmielisyys… piru hänet vieköön!
Se sinun vapaamielisyytesi, jota Ounasto on sinulle syöttänyt, ei ole
muuta kuin anarkismin häntä, tai sitten ahdasmielisyyden saparo…"

— "Sekaa kortit, äläkä filosofoitse!" — käski Horsma.


— "Anna Yrjön filosofoida", — tarttui Oolavi. Kortteja sakatessansa
jatkoi Harteva:

— "Heitä sinä, Oolavi, siis hiiteen se Ounaston oppi!… Eihän


vapaamielisyys ole muuta kuin olematonta lirun-lorua…
mahdottomuutta, koska sen, ollakseen vapaamielinen, pitäisi antaa
kaikkien tehdä mitä tahtovat… Tyrannienkin ja anarkistien sen pitäisi
antaa tehdä mitä tahtovat, sillä muutenhan se olisi
ahdasmielisyyttä… Risti on valttia…"

Kortit läiskivät taas. Hei-huudot säestivät läiskettä, ja rahat


vaihtoivat omistajia. Kun rahat oli jaettu, kysyi Ilanne paperossi
hampaissa:

— "Etkö sinä, Yrjö, ole enää puoluekarvaltasi 'ei-mikään'… kun


kehut anarkismia?…"

— "Eee-i!… En minä viitsi sitäkään olla… Minä olen kääntynyt


anarkistiksi", — ylvästeli Harteva, lyöden kortteja pöytään.

— "No sitten litkat sen päälle… Yrjön laskuun pullo pöytään…


Hei, viinuri… Hei!" — huusi Ilanne riemuissansa.

— "Viinuri, hei! Pullo pöytään, viinuri!" — tarttui Voima tanakkana.

— "Viinuri! Pullo pöytään… Hoi, viinuri!" — kaikuivat sekavat,


riemuisat huudot.

— "Mikä hätä on herroilla?" — hätäili huoneeseen kiirehtinyt


viinuri.

— "Yrjöstä on tullut anarkisti… Tiedätkö että Yrjöstä on tullut


anarkisti… Yrjöstä tulee rosvo", — kaikuivat sekavat ilohuudot
vastaukseksi viinurille.

— "Tuo miehen kokoinen pullo pöytään!… Yrjö on kääntynyt ja nyt


juodaan maljat", — jatkui rähisevän joukon huuto.

— "Konjakkiako vai punssia?" — yritti viinuri.

— "Tuo molempia!" — komensi Harteva sikari hampaissa, selkä


kenossa istuen.

— "Kuule!… Ja tuo sitruunaa ja kuumaa vettä!" — kehoitti Ilanne


pois kiirehti pääviinuria.

— "Vai anarkisti sinusta tuli!" — ihmetteli Horsma.

— "Anarkisti… Ja se oli vähä rutto kääntyminen. Ei siinä siekailtu


monta minuuttia", — mahtaili Harteva. Ja korttejansa tarkastaen hän
selitti:

— "Minä luin sitä Harhama-ryökäleen kirjaa ja siellä oli niin


syötävän voimallinen kuvaus anarkismista, että minä sanoin jotta
antaapa Hartevankin panna pommit soimaan…"

Yleinen naurun hohotus kuului tupakan savun seasta. Kortit


läiskivät taas. Rahat vaihtoivat kukkaroita. Oolavi retusi jo muiden
mukana, vaikka siivommin, ikäänkuin epäröiden. Harteva kehotteli
häntä:

— "Tule sinä, Oolavi, minun kanssani samaan pyöveli-joukkoon,


sillä kyllä se anarkismi on oikea usko… Miehen pitää olla toista tai
toista päätä, mutta ei välillä heiluvaa… Ja anarkismi on kerrassaan
repäisevä meininki… Minä sanon sinulle, Oolavi: Minä olen joko selvä
tai sitten täyshumalassa, mutta en koskaan hutikassa, sillä se on sitä
keskiväliä eli vapaamielisyyttä…"

Oolavin levoton luonne huumautui aina repäisevästä. Harhaman


kuvaukset Nikolain voimasta olivat häntä juovuttaneet. Siten oli
hänen sielussansa valmistunut maaperä kylvölle. Oras ei tosin vielä
tahtonut nousta, ei edes itukaan maahan ottaa, mutta siemen ei
enää myös pudonnut kalliolle: Hän sieti jo Hartevan rehentelyjä.

Viinuri toi juomat pöytään. Kortit olivat jaetut, mutta Horsma


ehdotti:

— "Levätään nyt ja juodaan… Konjakkiako sinä, Oolavi, otat vai


likööriä?"

— "Vaikka konjakkia!" — vastasi Oolavi huolettomana.

— "Minä juon molempia sekaisin", — ylvästeli Harteva, ja Oolavilta


hän kysyi:

— "Oletko sinä milloinkaan koettanut, miten paljon sinä 'vedät'?"

— "En ole koettanut", — vastaili Oolavi, kuin sivumennen.

— "Sinun pitää koettaa", — tarttui Harteva jatkaen: "Toisin


sanoen: sinun pitää mitata miten paljon sinuun mahtuu… että tiedät
kokosi… Kerran me luimme, että oikea saksalainen ylioppilas vetää
korin olutta ja mittasimme onko suomalainen ylioppilas yhtä suuri…"

— "Oliko yhtä suuri?" — tokaisi Oolavi, joka ei tahtonut näyttää


aralta, kokemattomalta.
— "Suurempi oli häijy", — ylpeili Harteva, — "Yksi kori ja viisi
pulloa mahtui… Mutta kyllä olikin silloin täysi… Könönen, joka on
semmoinen lyhyt pallukka, niin, Könönen, kuule, paisui niin
pyöreäksi, että vieriteltiin miestä kuin oluttynnöriä lattialla… Jos olisi
vielä pullo lisätty, niin halki olisi pahuus paukahtanut…"

Yleinen naurun rähäkkä palkitsi puhujaa. Harteva innostui:

— "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…"

— "Siis viina on muuttunut vedeksi", — pisti Voima naurun ja


rähinän seasta. Horsma oli istuutunut pianon ääreen, säesti sillä ja
lauloi täyttä kurkkua:

"Jos oisi täynnä viinaa kaivot ja lähteissä juoksisi viini, niin


saisivat rauhassa levätä aivot, ei riippua kirjassa kiini, kun ei
olis tarvis tutkinnolta, joitta nyt ei virkaa voida — ei tuomarin
virkaa, ei lääkärinkään — saada viinaa lypsämään."

Riemastunut seurue kertasi käheällä äänellä:

"Kun ei olis tarvis tutkinnoita, joitta nyt ei virkaa voida — ei


tuomarin virkaa, ei lääkärinkään — saada viinaa lypsämään."

Hoilotus ja nauru sekottuivat epäselväksi rähinäksi. Viini oli tehnyt


Oolavissa tehtävänsä ja yhteinen humu ja ilo alkoivat häntä
huumata, temmata mukaansa. Vähä kerrassaan valmistuneena alkoi
hän huomata, että elämässä on sitä mukaansa tempaavaa, jota hän
etsi Harhaman kirjan luettuansa: Hänelle alkoi jo, kuten
tuhlaajapojalle, kelvata ja maistua elämän rapa. Hänen veitsiterävä
järkensä ja luonteensa perinnäinen rehellisyys vaikuttivat, että hän
punnitsi asioita ja puheita ja voi siten vastakkaisissa asioissa
huomata kumoamatonta oikeaa, kuten nyt Hartevan todisteluissa
anarkismista, vapaamielisyydestä ja vanhoillisuudesta. Perinnäinen,
ehdoton totuus kietoutui siten hämäriin, sotkuisiin verkkoihin,
himmeni ja hukkui kokonaan ja epäilys alkoi orastaa yhä
kasvuvoimaisempana. Kepeistä asioista ja keskusteluista, samoin
kuin syvällisistäkin, jäi aina joku siemen, joka iti ja nousi elämän
suurkysymyksen oraalle. Kaikki kulki luonnollista tietä, kuten luonnon
valtakunnassa. Paha kehkeytyi hitaasti, mutta varmasti.

— "Kuka tekee työn?" — tiedusteli taas Harteva heittäen


korttipakan sekotettavaksi.

— "Väinön vuoro!" — kuului jonkun vastaus.

— "Älä valehtele, Aatun on nyt", — väitti Väinö Ilanne.

Syntyi pieni kinastelu. Aatu tenäsi vastaan, väittäen:

— "Minä tein viimeisen työn,"

— "Horsmapas sekasi viimeksi", — intti pari vastaan.

— "No, tuokaa sitten tänne, kun minä sekaan, ja rentonaan!" —


komensi Harteva.

Ja taas läiskivät kortit hei-huutojen säestyksellä. Rahoja


tasailtaessa tiedusteli Harteva Oolavilta:

— "Tunnetko sinä, Oolavi, jo korttitytöt?"


— "Oolaviko?… Oolavihan se teki niistä korttipakan", — vastasivat
toiset yhdestä suusta, ennen kun Oolavi ehti myöntää.

— "Älä nyt!" — ihmetteli Harteva silmät pyöreinä päässä. Oolavi


hymyili. Hän nautti sankaruudestansa.

— "Niiden korttipuvut ovat Oolavin ostamat", — selitti vielä


Horsma, rähinän seasta.

Harteva riemastui ja huudahteli:

— "No vie sua!… Joko sinä olet ehtinyt niin syvältä saada elämää
kiinni!… Mutta se oli mainio keksintö!… Sinusta, Oolavi, tulee kohta
mies."

— "Oooo! Sinä et, Yrjö-veikkonen, tiedäkään, mitä Oolavi jo


tietää!" — vakuutti innostunut Ilanne.

— "No, Oolavin malja sitten!… Juo, Oolavi", — räyhäsi Harteva.

Lasit tyhjennettiin. Eläköön-huudot kaikuivat savun seasta. Oolavi


oli ylpeä, kun oli suorittanut tehtävän, joka ihastutti toisia, etenkin
Hartevaa. Harteva selitteli:

— "Nyt niillä tytöillä onkin omat nimensä: Hertta — no se on


vanha nimi — se suurin tytön votkale on Ruutu ja ne toiset sitten
Risti ja Pata… Eilen tanssi Pata heipparillaa ja pormestari istui
silinteri päässä, kun yleisö oikein innostui: huudettiin niin turkasesti
'hyvä', että seinät soivat… Ja kukkia kun viskottiin, niin niitä tuli kuin
heinävihkoja… Forsmanin Pekka silloin innostui niin, että kiireessään
sieppasi pormestarin päästä silkkipytyn ja nakkasi sen näyttämölle,
että hei vaan!…"
— "Eikö naurettu pytylle?" — tiedusteltiin Hartevalta naurun
seassa.

— "Naurettiin… Niin nauroin minäkin, että tuppi heilui", — vakuutti


Harteva.

— "Entäs miten pormestarin älypytylle kävi?…"

— "Miten sille kävi!… Hyvästihän sille kävi: Pata potkaisi sen


takaisin, että komahti vain tyhjä pytty, ja pormestari sieppasi
omansa lennosta kiinni!" — selitti Harteva, välinpitämättömänä
rehennellen ja ihmetellen.

— "Pahuus kun minä en sattunut siinä ötäkässä olemaan", —


päivitteli Horsma päätään raapien. Kulauttaen lasinsa tyhjäksi, ilmotti
Harteva:

— "Tiedätkö, Oolavi, että pormestarin Bertta on sinuun pikiintynyt


korvalehtiään myöten?"

— "Älä nyt lorise!" — yritti Oolavi mielihyvillään.

— "Ja entäs Kauniston Esteri!… Se on kanssa!" — lisäsivät toiset


meluten ja räyhäten, Harteva jatkoi vakuutustansa. Lyöden nyrkkinsä
pöytään vannoi hän:

— "No kun minä sanon, niin se pitää paikkansa kuin taivaan


valtakunnan perustus, pyhä Pietari… Ja arvaa miten varmasta
paikasta minun tietoni ovat!"

— "Omasta päästäsi… Kellä on pata-ässä?" — vastasi Oolavi pelin


lomassa, tekeytyen välinpitämättömäksi, mutta itse asiassa, nauttien
ilmotuksesta.
— "Huonommasta lähteestä sentään", — ylpeili Harteva, selittäen:
"Renlund on Berttaa hakkaillut jo toista vuotta ja oli jo päässyt
salakihloihin asti, kun Bertta pyöräyttikin pojalle rukkaset ja komeat
pyöräyttikin…"

— "Onko Renlund saanut rukkaset!… Renlundin Kustiko on saanut


rukkaset… Älä nyt vain perättömiä valehtele!… No sitten saadaan
yksi mies lisää joukkoon!" — iloitsi koko joukko niin että ääntä tuli
yhtenä humuna ja rähäkkänä.

— "On saanut",— vakuutti Harteva, jatkaen: "Eilen jo tuli itse


luokseni ja pyysi ryypyille… Ja kun oli vähän aikaa kallistettu, niin
että Renlundilta kieli pääsi kahleistansa, niin sanoi että… niin
surkealla äänellä vielä sanoi, että: 'Minä juon nyt harmista, sillä
Bertta on nyt mennyt minulta ijäksi'… Kun minä syvemmältä häntä
tutkin, niin hän sanoi suoraan, että sinuun hän, Oolavi, katsoo
kierolla silmällä… Mutta älä sinä huoli Bertasta! Sen kanssa saat
pahankurisen anopin ja vähä rahaa!"

— "En minä huoli kenestäkään", — kerskui Oolavi.

— "Se on oikein!" — huusi riemastunut seurue, korttien läiskiessä.

— "Jää vainenkin pyhäksi vanhaksi pojaksi… Minäkin aijon siksi


munkiksi ruveta", — mahtaili Harteva, puhallellen pitkiä savuja ja
jatkaen:

— "Mutta naimisiin minä en silti mene… Ennen panttaan nahkani


pirulle, kuin rupean avioliitolla elämään…"

— "Älä nyt ylpeile!… Kun tulee viimeinen tiukka, niin menet vain
naimisiin kuin poika," — puuttui juopunut Horsma.
Harteva vannoi mahtipontisena:

— "En vaikka naukuisi… Ja tiukka ei tule, sillä minä rupean


virkamieheksi!"

Joukko hämmästyi. Joku huomautti:

— "Entäs tutkinto?…"

Harteva reuhasi edelleen:

— "Tämä poika ei huoli tutkintoviroista… Minä rupean


arvostelijaksi… herra arvostelijaksi…"

Yleinen naurun hohotus palkitsi puhujaa. Sen seasta kuului huuto:

— "Yrjö on herra arvostelija…"

— "Mitä sinä arvostelet?" — tiedusti Oolavi. Harteva teki mahtavan


liikkeen ja ylpeili:

— "Minä rupean arvostelijoiden arvostelijaksi… Arvostelijakeisari


minä olen… Ja kun minä arvostelen, niin siinä pitää jymyn kuulua!…
Minä arvostelen koko maailman, että rytisee… Hei vaan!"

— "He-hei!" — hihkaisi seura, kädet ojoina.

Korttipeli, juominen ja reuhaaminen jatkui aamuyöhön. Seurue


kävi
aina vain äänekkäämmäksi. Rahapanokset suurenivat, savu sakeni.
Miehet raatoivat savun seassa, kuin riihiväki pölyisessä riihessä.
Huudot, laulut ja pöyhkeilyt vuorottelivat. Pois lähtiessä selitteli
Harteva Oolaville:
— "Kadulla… minä… sanon kaa… ka… kadulla… kadulla pitää olla
herrasryhti: Astunta topakka… katse ylpeä… näin… vä… väh… vähä
yläviistoon… ja keppi kee-eppi tällä lailla… Edelleen… sikari aina
tässä asemassa soo… soor… sormien välissä… ja mahtia… maa…
ahtia sitä pitää olla… Se kaikki kuuluu korkeampaan sivistykseen… ja
varsinkin se koo… ko… korottaa miehen neron kurssia…"

Itäinen taivaanranta raottui jo aamuruskoksi, kun Oolavi saapui


asuntoonsa. Joku sanomattoman ilkeä, vastenmielinen tunne täytti
silloin taas koko hänen olemuksensa. Hän inhosi kaikkea. Kun hän
laski nyt rahojansa, huomasi hän menettäneensä yli kolmetuhatta
markkaa. Epätoivo valtasi hänet silloin, kuten jo usein ennen. Hän oli
jo menettänyt suuria summia, oli aina toivonut voittavansa ne
takaisin ja sitten lakkaavansa, saatuansa siten peitetyksi
pankkitalletuksiin tekemänsä vajauksen. Sielun ja ruumiin voimat
raukesivat hetkeksi kokonansa. Päihtymys meni ohi ja käsittämätön
tuska ja inho raateli häntä armottomin kynsin.

Tuskaisena tarkasti hän taas saapuneen postin ja luki Martvalta


tulleen kirjeen. Vaistomaisesti, kuten aina hätäytynyt, tarttui hän nyt
Martvaan, joka tuntui enkeliltä, ainoalta, joka hänet pelastaa. Ja
kumminkaan hänellä ei ollut enää voimaa eikä rohkeutta paljastaa
mitään, ei palata hänen luoksensa. Hän oli jo mennyt liian kauvas.
Siksi oli paluu vaikea. Hän yritti jo tunnustaa kaiken: kirjoitti kirjeen,
mutta kirje tulikin taas toisenlainen kuin hän olisi tahtonut. Hän
salasi kaiken. Hän sirotteli koko kirjeen lemmenkukilla ja puhtailla
ajatuksilla. Ainoa mikä siinä ilmaisi jotakin, olivat loppuun liitetyt
kaksimieliset sanat: "Kuten tiedät matkustan lukujeni vuoksi
Pietariin. Et tiedä miten sinua kaipaan ja miten tarvitsisin sinua
nähdä luonani ja puhua kanssasi."
Kokoon menehtyneenä, ikäänkuin mäsäksi lyötynä vajosi hän
istumaan, kutistui aivan lyyhyyn, kärsi ja kauhistui nykyistä tilaansa.
Se kauhu ja epätoivo masensi hänen voimiaan edelleen. Ruumiinkin
voimat loppuivat niin tyyten, ettei hän jaksanut enää liikahtaa,
hengitys muuttui kuumeiseksi, katse epätoivoiseksi. Hän alkoi hiota
ja vapista. Voimattomat kädet riippuivat polvilla rentoina ja alas
nuokahtanut pää painoi hartioitakin kumaraan.

Kun kiusaaja mustia kukkia kylvi.

Elämä ja kuolema kulkivat käsi kädessä. Kalman mailla ajatteli


neito surullista elämänlauluansa.

Oli tyynen kesäisen päivän kaunis sävy… Hautausmaalla


heilahtelivat tuonen liinat… Kuoleman kukat nyökyttivät siellä
surullisina… Päivä paistoi suruja maille ja kuoleman kaunis runous
puki kaiken rauhaisimpiin liinoihinsa… Ei risahtanut, ei hisahtanut…
Kuoleman hiiri kurkisti kivenkolosta ja Tuonen kissat hiipivät hiljaa
ruohokossa…

Kuoleman kauniina enkelinä seisoi Martva hautausmaalla… Hän


seisoi kauniin puun alla, sen runkoon hieman nojaten… Tuoni
tuoksui, kalma kylvi rauhojansa ja kuolema kehräsi elämänvirttä,
kehräsi sitä, kunnes katkesi säije.

Martva tajusi kuoleman suuren tarinan… Hän huomasi sen rukin


rullaavan, näki miten on heikko elämänrihma: Se juoksi miltei
näkymättömänä, solui kuoleman hyppysten lävitse… Kaikki kertoi
kuoleman suurta satua, lauloi sen rukin hyrinätä… Hauta ruohottui,
risti lahosi… Jotkut mätänivät jo maassa, toiset seisoivat kallellansa…
Kuoleman voittopatsaina odottivat ne omaa kuolemaansa…

Jo alkoi vavahdella Martvan mieli… Kuoleman rukit hyrisivät niin


surullisesti… Elämänrihma hienoni hienonemistansa ja solui
kuoleman rukin rullalle. Martva mietti elämän ja kuoleman suurta
tarua, kuunteli kalman kertomusta… Likimäisnä, hänestä hieman
oikealla, kohosi pieni, kaunis, vaatimaton Ranniston kanta-isän
hautaristi… Sen koristeena oli kukkasia… Ne kukat oli sinne Martva
eilen tuonut…

Päivä paistoi, kuoleman sirkka sirisi… Hienona hyminänä vieri


kuoleman suuri virsi… Martva mietti elämän surullista runoutta:
Elämä kaikkinensa avautui hänelle niin kuin kaunis kukannuppu… Se
tuoksui runollista ikävää… Hän käsitti paljon… Hän ymmärsi
elämän… Hän huomasi, että siitä puhkeaa ihana, armas kukka:
kuolonrauha… Se rauha hohti jo surukukkana hänen edessänsä… Se
koristi Litvan kaunista hautausmaata…

Tuuli nukkui… Tuoni ripsehti askareillansa… Kaunis enkeli suri


koivikossa, itkien Martvan kohtaloa. Koivu huokui hartautta… Tuonen
tytöt hiipivät kylmät sukat jalassa… Ne katselivat kaunista Martvaa ja
itkevää enkeliä… Enkeli laskeutui ristin juureen polvillensa ja rukoili
Martvan puolesta:

"Oi, Isä! Sääli Martva rukkaa! Et hälle kova olla saa! Sa


hoida häntä, ihmiskukkaa! Jo suru silmää sumentaa häneltä.
Toki kyyneleitään Sä ällös päästä vuotamaan, vaan anna
kuivin poskin teitään rakkaasi käydä ainiaan!"

Kirkonkello kumahti kauniiksi aameneksi… Se kumahti hiljaa sekä


kirkkaanheleänä… Sen ääni sointui rukoukseen, niinkuin nuoren
tytön kauneus sulautuu hänen ilta-ikäviinsä… Rauha värähti…
Tuonen lintunen nukahti… Kesä-illan kauneus vierähti korkeimmaksi
runoudeksi… Surullaan ja ihanuudellansa herkytteli se Martvan
mielen.

Jo oli hän miettinyt elämäntarunsa… Kuoleman maalla oli hän


katsellut elämänkukkaa… Hän oli nähnyt elämän runouden: onnen,
joka puhkeaa ikävästä… Hän oli tuntenut ikävän, joka puhkeaa jalon
sielun ylevyydestä… Elämänruno suureni… Se tuli surullisemmaksi…
Sitä miettiessänsä lausui hän ajatuksissansa:

— "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!"

Kuolema istui kylmä kantele polvillansa… Mutta ei koskenut sormi


soiton kieleen… Kuolokin katseli kaunista neitoa… Siksi jouti soitto
jouten olla… Silmät maahan taas luotuina jatkoi Martva surullista
puhettansa:

— "Nyt tässä, rauhaisella kalman maalla taas kerron Sinulle, Isä,


huolistani… Et saa vain siitä, Isä, vihastua… En tiedä miten alkaa
puheluni… Jotakin hämärää on edessäni ja näen nyt jo jotain
surullista ja himmeätä… suurta… kaihoisata, jota en jaksa vielä
ymmärtää… Vaan kuinka liekin: Jos Sinä, Isä, tahdot Martvaasi
kerran myöskin koetella, kuin muinoin palvelijaasi Jobiakin, niin
kuule, hyvä, rakas Isä, ällös tee sitä toki liian ankarasti!…"

Enkeli kumartui itkemään… Kuoleman silmässä kiilsi kyynel…


Tuska vieri virtenä, suru säveleenä. Martva jatkoi surullisena:

— "Minä ehkä napisin nyt tässä äsken, vaan muutakaan en,


raukka, tehdä voi… Oi, Isä, näethän miten heikko olen. Siis
rankaisekin minua lempeästi!… En tahtoisi minä vitsaasikaan välttää,
jos luulisin vain kestäväni, mutta minä, kurja, pelkään omaa
heikkouttani… Sen vuoksi suo minun nurkua nyt näin."

Elämänkukkanuppu avasi lehtiänsä hänelle… Niiden alta näkyi


elämänturhuus ja kuoleman värit… Hän mietti… mietti kauvan. Sitten
lopetti hän surullisena rukoilunsa:

— "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ä!…"

Kuolema kumartui surullisena… Mykäksi kävi Tuonen kannel…


Kukka suri, päivä itki… Tuonelan pieni tyttö käveli koivikossa ja kylvi
sinne surukukkia helmastansa… Martvan mielessä värisi miete. Hän
hellitteli sitä hetken ja antoi sen sitten vierähtää surullisiksi sanoiksi:

— "Suo minun yhtä tässä hautausmaalla Sinulta, Isä, vielä pyytää


nyt: Suo elämästäni minun kerran jättää niin kaunis muisto, ett'ei
haudallani kiroa kukaan, vaan tuo siihen kukan tai lausuu siinä
pienen siunauksen… Niin, Isä… kuule… ole armollinen!… Martvaasi
älä hylkää milloinkaan!"

*****

Suuri elämän sururuno oli loppuun lausuttu… Sirkka sirahti


kerran… Tuoni ripusti puuhun kanteleensa… Kuolo seisoi terävä
viikate kädessä…

Martva istahti pienelle hautakummulle… Siinä mietti hän sitä


himmeää, josta oli äsken puhunut… Ei liikahtanut taaskaan
tuulenhenki… Koivun oksilla riippui päivänpaisteen kirkas suruharso…
Se riippui repaleisena pukien koivun surun autereeseen… Oksalla
istui lintu äänetönnä, pää kallellaan… Kuolema runoili suruja, elämä
mielen apeaa ja koko luonnonsävy oli niin suruista ja kaihoisata kuin
olisi se itkuun pillahtamaisillaan…

Äkkiä värähti valo… Tuonelan neidot hiipivät hiljaa piiloihinsa…


Kaikki hiljeni, kaikki odotti… Tietä myöten lähestyi Perkele,
rauhallisena kulkijana, vyöllä Harhasaaren avain… Väsyneenä istahti
hän hautakummulle, matkasauvaansa nojaten… Oudostuneena
huudahti Martva hänelle:

— "Sinäkö yksinäinen taaskin täällä!… Missä olet nämä päivät


vaeltanut, kun näytät matkastasi väsyneeltä?"
Murheellisena, sauvaansa nojaten selitti Perkele hänelle:

— "Ah, minun kulkuni ja minun tieni!… Ne ovat niin kuin taivaan


tuulen polut… Ei niitä sido matkasuunnitelmat… Vapaasti kuljen…
Yhtä vapaasti myös surullisen luokse tieltä poikkeen."

Hänen äänensä lumosi kuin taikasoitto… Katse poltti neidon


povea…
Ihastuneena huudahti Martva:

— "Oi, onnellinen, kun saat kaikkialla suruista lohduttaa!…


Tuskainen, jonka löytää elämästä, on kaunein sekä kiitollisin kukka…
Ei kuihdu se, ei lakkaa tuoksumasta jaloa, suurta kiitollisuuttansa…
Ah, jospa minä kerran kastaa voisin sen iki-kauniin kukan
kyynelilläni!… Vaan luultavasti näillä matkoillasi on myöskin jotain
muuta tehtävää…"

Yhä lumoavampana kuului Perkeleen ääni, kun hän selitti:

— "On suurin tehtäväni ilmotella, mistä on se onni, tieto


saatavana, se onni, jota suuri ihmishenki alati ikävöi… Ah, miten
harva tässä elämässä sen onnen löytää!… Epätoivoissansa niin moni
siksi suistuu turmioon…"

Hänen äänensä väreili sääliä täynnä… Hänen suruinen katseensa


soitteli sydämen hellintä kieltä… Säälistä sulaen lausui Martva
hänelle:

— "Ai, miten suuren toimen Jumalalta oletkin saanut


suoritettavaksi!… Vaan tokko löydät ketään matkoillasi, joka ei tiedä,
että kaikki onni on saatavana aina Jumalassa?…"
Perkeleen silmäykset kiemahtelivat kuin kavalat käärmeet… Ne
kietoivat viattoman neidon. Kavalana vastasi Perkele:

— "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…"

Suuri lumous sokaisi jo Martvaa… Ajatus raukesi… Hän epäröi…


Lumous lisääntyi… Ajatuksissansa lausui hän:

— "Sanasi ovat aivan uutta kuulla."

Suuret epäilyn voimat alkoivat raataa: ne hämärtivät sielun…


Martvan mieli hajosi, tuli herkäksi… Surulliseksi tekeytyen huokaili
Perkele:

— "Ah, moni uskoo, että ihmiselle on Luoja velvollinen


valmistamaan ilon ja onnen tässä elämässä: On moinen usko Luojan
kiusaamista… Se laiskuria kyllä lohduttaa…"

Elämän-ongelma himmeni… Outo ääni kutitteli korvaa…


Mietteissänsä lausui Martva:

— "En ole sitä ajatellut!"

Hän sotkeutui kiusaajan lumosanoihin. Yhä murheellisempana


huokaili
Perkele:

— "Ah, miten moni Häntä kiusaakaan!… Valmiiksi Häneltä monet


odottavat elämän onnea kuin kerran kansa mannaa… Ja kumminkin
on Luoja ihmiselle elämän valmistanut siksi maaksi, josta on se onni,
rauha etsittävä!… Niin: ohdakkeiden, orjantappuroiden seasta on se
onni otettava… Uskotko sitä, Martva?… vastaa nyt!…"

Kauneimmat soitot lumosivat Martvan mieltä… Hän näki itsensä jo


syyllisenä… Masentuneena lausui hän:

— "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…"

Kyynel kierähti kauniiseen silmään… Povessa oli jo sydämen täysi


suruja… Kavalana lohdutteli Perkele:

— "Hän myös on hyvä sekä armollinen… Jos käännyt aikanansa,


sekä lähdet vihdoinkin oman käden varaan, niin… Hän silloin vielä
kaikki unohtaa…"

Kyynel kierähti… Mieli värähti… Hieman rauhottuen myönteli


Martva:
"Niin… Sen uskon. Hän on ihmeen hyvä… Vaan mitä pitää minun
tehdä nyt?"

Suuri henki tekeytyi miettiväksi.

— "En tiedä… Luulen toki, että sinun on lähdettävä nyt jo


kotoasi… Siis lähde nyt ja ota ilman Luojaa elämän ohdakkeista
onnen-rauha!… Niin tottelet myös Häntä: Jumalaa…"

Yhä masentui Martvan mieli… Kiusaajan ääni soi hänelle


soimaavana… Käsi herposi helmaan… Hän lausui miettivänä,
selitellen:

— "Ah, nyt en enää tiedä mitä tehdä… Ei linnunpoika tohdi


siivetönnä pesästä lentää… Täytyykö minun sitten turvatonna pois
isän luota maailmalle mennä?… Se kotoani lähtö olisi samaa kuin
Hänen, Luojan luota poistuminen…"

Pahastuneeksi tekeytyen lausui Perkele kuivasti:

— "Tee mitä tahdot!… Minun tehtävääni ei kuulu koskaan


kehotteleminen… On siinä kyllä, että näytän tien."

Kaukaa kuului suruinen soiton hyminä… Se toi mieleen uusia


suruja… Ihmishenki oli jo suurissa lumoissa… Mielipahoillaan lausui
Martva:

— "Ah, kiitos neuvostasi, tuntematon!… Vaan älä pahastu, jos


epäilenkin niin suurta asiata miettiessä… Näethän, miten avuton taas
olen… Siis älä suutu, mutta sääli minua!…"

Huoaten lausui siihen Perkele:


— "En pahastu suorasta puheestasi… Jo olen näillä matkoillani
saanut semmoisiin loukkauksiin tottuakin… Niin on se jo ollut, niin on
vielä nytkin: Jokainen puolustautuu verukkeilla, kun tahtoo jättäytyä
Isän varaan, peljäten että Sinain korpikulku on vaivaloinen omin
jaloin käydä… Jokaista miellyttävät Isän lihapadat…"

Hätäytyneenä puolustautui vielä lumottu ihmishenki… Anteeksi


pyytäen vaikersi Martva:

— "Älä soimaa, mutta ymmärrä minua!… Enhän minä tahdo


napista, enkä olla paha… Vaan isän luota lähtö oudostuttaa… Tai
pelkään, että se on ehkä väärä… Niin lähti Isän luota myöskin kerran
tuhlaajapoika kauvas maailmalle…"

Kerkeästi tarttui siihen suuri henki. Kavalana selitti hän:

— "Tuhlaajapoika lähti tuhlaamaan… Vaan annan sinulle toisen


esimerkin: Näes, Jeesus myöskin lähti Isän luota. Hän tuli lihaksi ja
kärsi, kuoli… Ei nurissut Hän sitä tehdessänsä!… Tekikö Hänkin
väärin mielestäsi?…"

Suuri lumous täytti Martvan sielun. Hämmästyksen lyömänä


huudahti hän:

— "Sitä en ole koskaan ajatellut!… Nyt kiitän tästä


huomautuksestasi!…"

Hän alkoi äsken kuulemaansa ajatella… Murhe täytti mielen


kokonaan… Hän mietti kotoa maailmalle lähtöä… Hän istui
hautakummulla kuin turvaton linnunpoika pesän reunalla… Siipi
tuntui vielä heikolta, maailma kylmältä… Ristin takaa kurkistelivat
häntä kuoleman neidot… Kaikki tuntui turvattomalta… Epäröiden
lausui hän silloin:

— "En tiedä mitä tehdä… Minä pelkään… Enhän minä, raukka, ole
suuri Jeesus… Oi! eivät Hänen työnsä minulle sovi."

Kerkeänä huomautti kiusaaja siihen:

— "Se huomautuksesi on aivan totta… Vaan tiedä myös: Hän antoi


esikuvan…"

Koko Martvan sielu tulvi täyteen elämän epäselvyyttä.


Hämmästyneenä huudahti hän kiusaajallensa:

— "Nyt muistan sen!… Ah, miten ihmeen hyvin tunnetkin sinä


koko pyhän kirjan!… Vaan sano mitä ihmeen tehtävätä minulla olisi
siellä elämässä?"

Kavalana vastasi hänelle Perkele:

— "Siellä odottaa sinua sulhasesi… Ethän tiedä, vaikka hän


tarvitsisi sinun apuasi!…"

Nopeasti huudahti siihen kiusattava:

— "Ei… ei!… Nyt erehdyt… Ei Oolavini milloinkaan kaipaa minun


apuani!… Se, joka laskee kuohuvimmat kosket, ei joudu koskaan
maailmalla hätään!"

Silloin Perkele alkoi loihtia hänen eteensä mustia kukkia… Hänen


enkelinsä sirotteli niitä neidon suurimmiksi suruiksi… Hän puhui
kavalana:
— "On nuori, kaunis mies maailmalla alati suuren vaaran
alaisena… Hän kulkee neidon paula kaulassansa… On neidon paula
pahin hirttonuora…"

Hautausmaan kukkaset alkoivat jo mustiksi muuttua… Järkkynyt


Martvan mieli ei kestänyt sitä suruista näkyä… Perkeleen silmäykset
sirottelivat häneen yhä uusia mustia kukkia… Hän huudahti jo
hätäytyneenä:

— "En usko sitä… Miksi Oolavista semmoista puhut?… Hän on


puhtain, jaloin kaikista ihmisistä maailmassa…"

Perkele loihti hänen eteensä hienot lemmen hämärät: Kauniissa


lehdossa, kaukana näkemän rajalla, käveli kaksi varjoa vieretysten…
Ei tuntenut vielä neito omaansa… Metsä oli hämärä, varjo himmeä…
Mutta hän aavisti sen Oolavin olevan… Pieni tyttönen sirotteli siellä
helmastansa mustan kukan siemeniä…

Kylmänä, kiehtovana selitti Perkele:

— "Niin, sulhasesi kyllä kosken laskee… Vaan nainen onkin rikkaan


miehen tiellä pahempi kivi kuin on kosken kari…"

Mustan kukan siemenistä nousivat jo kukan taimet… Hämärä


hälveni, varjot selkenivät… Martvan mieli otti suuria suruja…
Kiusaaja lisäsi kavalana:

— "Mies kyllä aina kiertää kosken kiven, vaan naista hän ei


konsanansa kierrä…"

Mustan kukan taimet kasvoivat… Jo pääsivät ne kukkanupulle…


Lehto oli niitä aivan mustanansa… Hämärä haihtui… Martva tunsi jo
Oolavinsa… Musta kukka vei häneltä mielen maahan…
— "Ah, nainen pettää kaikkein viisaimmankin", — huokasi silloin
suuri henki.

Mustan kukan umput alkoivat jo kukiksi puhjeta… Musta väri


koristi kaunista metsää, kyynel neidon silmää… Hätäytyneenä
huudahti Martva:

— "Oi, toteutuukohan pahan enne!… Tuottaako Oolavini minulle


tuskaa?… Ei Jumalaa hän toki unohtane!…"

Mustan kukan tuoksu täytti ilman… Tyttö kärsi… Kukka puhkesi


puhkeamistaan… Hämärä selkeni… Varjo häilähteli jo naisen
muodossa… Yhä sokaisten, yhä lumoten lausui Perkele:

— "Ah, suokoon Korkein hänelle viisautta jokaisen naisen


kavaluutta kiertää!… Ei hänelle muista turvaa lienekään!"

Musta kukka heloitti jo kauneimmillansa… Martva näki varjon


muuttuvan kauniiksi tytöksi… Silmä kertoi jo kyynelillänsä mitä oli
hänellä povessa… Avuttomana, rukoilevana lausui hän
kiusaajallensa:

— "Sääli minua, jätä soimaaminen!… Näethän kuinka raukka nyt


jo itken… Olen valmis uhraamaan nyt elämäni, jos sillä voin vain
hänet pelastaa… Olen valmis kosken kuohuun viskautumaan…"

Yhä kauniimpana kukki musta kukka… Sen värit koskivat kipeästi


neidon mieleen… Kyynel vuoti karvaimmillansa… Hämärä selkeni…
Kiusaaja loitsi Martvan eteen lemmen näyn: Oolavi käveli neiti
Iltamon keralla… Silmä puheli silmän, käsi käden kanssa…

— "Oi!" — huudahti heikosti Martva.


Mustat kukat kukkivat kauneina… Näky jatkui… Oolavi lauleli jo
neidollensa… Martva vapisi… Hän oli maan alle vajoamaisillansa…
Hädän-ilme kasvoillansa kavahti hän ylös… Hän oli valmis lähtemään
elämään… lähtemään sinne Oolavin avuksi… Lemmenkateisena
huudahti hän tuskaisen huudon:

— "Oolavi!… Oi, Oolavi! Nyt viepi jo minua koski!"

Kun morsian avuksi lähteä päätti.

Entisyyden iloja haudattiin. Lattialla tuoksuivat hautajaishavut.

Ranniston tuvan seinänsaumat katselivat surullisina, ollen kuin


murhetta täynnä. Kissa hyräili lattialla. Päivä paistoi ikkunasta. Se
paistoi surullisena, paistoi kuin mielipahoillansa. Elämän kellot soivat,
vaan ei ollut iloa niissä. Tuntui kuin olisi tuvassa äsken ollut
hautajaiset.

Martva oli juuri vatvonut villat sekaantumaan ja istui nyt, kartaten


niistä lepeitä. Kartta liikkui kepeästi. Pii otti piihin hellävaroen, tuskin
hennoten siihen kosketella. Karttaajan mieli oli suruja täynnä ja siitä
oli tupakin surunsa saanut.

Kartatessansa hyräili Martva laulua: "Ja kuoleman nunnaksi


morsian lähti". Hän lauloi:

"Etäällä kauniissa linnassansa


kuningas istuvi loistossaan.
On nuori morsian rinnallansa
ja häitä suuria laitetaan.
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.

More than just a book-buying platform, we strive to be a bridge


connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.

Join us on a journey of knowledge exploration, passion nurturing, and


personal growth every day!

ebookmasss.com

You might also like