Book Image

Hands-On Functional Programming with C++

By : Alexandru Bolboaca
Book Image

Hands-On Functional Programming with C++

By: Alexandru Bolboaca

Overview of this book

Functional programming enables you to divide your software into smaller, reusable components that are easy to write, debug, and maintain. Combined with the power of C++, you can develop scalable and functional applications for modern software requirements. This book will help you discover the functional features in C++ 17 and C++ 20 to build enterprise-level applications. Starting with the fundamental building blocks of functional programming and how to use them in C++, you’ll explore functions, currying, and lambdas. As you advance, you’ll learn how to improve cohesion and delve into test-driven development, which will enable you in designing better software. In addition to this, the book covers architectural patterns such as event sourcing to help you get to grips with the importance of immutability for data storage. You’ll even understand how to “think in functions” and implement design patterns in a functional way. By the end of this book, you’ll be able to write faster and cleaner production code in C++ with the help of functional programming.
Table of Contents (23 chapters)
Free Chapter
1
Section 1: Functional Building Blocks in C++
7
Section 2: Design with Functions
12
Section 3: Reaping the Benefits of Functional Programming
17
Section 4: The Present and Future of Functional Programming in C++

OOP versus functional design styles

An important part of my job is to work with programmers and help them to improve the way they write code. To do so, I try my best to come up with simple explanations for complex ideas. I have one such explanation for software design. Software design is, for me, the way we structure the code such that we optimize it for business purposes.

I like this definition because it's plain and short. But one thing bugged me after I started experimenting with functional constructs; that is, functional programming leads to code such as the following:

const Sums sumsWithFunctionalLoopsSimplified(const vector<int>& numbers){
Sums theTotals(
sum(filter(numbers, isEven)),
sum(filter(numbers, isOdd)),
sum(numbers)
);
return theTotals;
}

Writing similar code in OOP style would most likely mean creating classes and using inheritance. So, which style is better? Additionally, if software design is about code structure, is there an equivalence between the two styles?

First, let's take a look at what the two design styles really promote. What is OOP? For many years, I believed all the books that listed the following three properties of object-oriented languages:

  • Encapsulation
  • Inheritance
  • Polymorphism

Alan Kay, the thinker behind OOP, does not really agree with this list. For him, OOP is about communication between many small objects. As a biology major, he saw an opportunity to organize programs like the body organizes cells, and to allow objects to communicate much like cells do. He places more importance on objects over classes, and on communication over the commonly listed OOP properties. I would best summarize his position as follows: the dynamic relations in the system are more important than its static properties.

This changes a lot about the OOP paradigm. So, should classes match the real world? Not really. They should be optimized for the representation of the real world. Should we focus on having clear, well-thought out class hierarchies? No, since those are less important than the communication between objects. What is the smallest object that we can think of? Well, either a combination of data, or a function.

In a recent answer on Quora (https://www.quora.com/Isnt-getting-rid-of-the-evil-state-like-Haskells-approach-something-every-programmer-should-follow/answer/Alan-Kay-11), Alan Kay stated an interesting idea when answering a question on functional programming. Functional programming came from mathematics and from an effort to model the real world in order to enable artificial intelligence. This effort hit the following problem—Alex is in Bucharest and Alex is in London can both be true, but at different points in time. The solution to this modeling issue is immutability; that is, time becomes a parameter to functions, or a data member in the data structures. In any program, we can model data changes as time-bound versions of the data. Nothing stops us from modeling the data as small objects, and the changes as functions. Additionally, as we will see later, we can easily turn functions into objects and vice versa.

So, to summarize, there's no real tension between OOP as Alan Kay meant it and functional programming. We can use them together and interchangeably, as long as we focus on increasing the immutability of our code, and on small objects that communicate with one another. We'll discover, in the following chapters, how easy it is to replace a class with functions and vice versa.

But there are many ways to use OOP that are different from Alan Kay's vision. I've seen a lot of C++ code with my clients, and I've seen it all—big functions, huge classes, and deep inheritance hierarchies. Most of the time, the reason I'm called is because the design is too hard to change and because adding new features slows down to a crawl. Inheritance is a very strong relationship and overusing it leads to strong coupling, and, therefore, to code that's difficult to change. Long methods and long classes are harder to understand and harder to change. Of course, there are situations when inheritance and long classes make sense, but, in general, going for small objects with loose coupling enables changeability.

But classes can be reused, can't they? Can we do that with functions? Let's visit this topic next.