1 Introduction to functional programming
This chapter introduces functional programming as a complementary way of thinking and coding in C++. Instead of prescribing step-by-step commands, the functional style declares what result is desired by composing functions and evaluating expressions. Positioned against imperative and object‑oriented habits, it encourages expressing intent at a higher level of abstraction, prioritizing clarity, safety, and concision. It also notes that while pure functional languages remain niche, mainstream languages—including C++—have steadily adopted FP ideas, making C++ a practical, multiparadigm host for this style.
Through a simple “count lines in files” task, the chapter contrasts loop‑heavy, stateful code with functional solutions that use standard algorithms and composition (for example, moving from manual loops to counting with library algorithms, mapping with transformations, and finally expressing the pipeline cleanly with ranges). The shift highlights core FP ideas: pure functions with no observable side effects, minimized mutable state, composability via function composition, and “lifting” functions from single values to whole collections. Thinking functionally means describing how inputs are transformed into outputs, not managing intermediate control flow and state.
The benefits emphasized include brevity and readability, improved correctness from purity, and easier concurrency because independent, side‑effect‑free computations require less synchronization. Relying on well‑optimized standard abstractions also enables “continuous optimization” as compilers and libraries improve. The chapter situates FP within C++’s evolution: templates and the STL enabled generic, higher‑order patterns early on; later features like lambdas and auto made FP more ergonomic; and newer additions such as ranges (with concepts and coroutines on the horizon) further streamline declarative, composable designs. It sets the stage for learning higher‑order functions, immutability, ranges, algebraic data types, and monads to build safer, more expressive C++ systems.
The program input is a list of files. The program needs to return the number of newlines in each file as its output.
If you allow the user to modify the text while you’re saving it, incomplete or invalid data could be saved, thus creating a corrupted file.
If you either create a full copy or use a structure that can remember multiple versions of data at the same time, you can decouple the processes of saving the file and changing the text in the text editor.
This example needs to modify a couple of independent variables while counting the number of newlines in a single file. Some changes depend on each other, and others don’t.
When thinking functionally, you consider the transformations you need to apply to the given input to get the desired output as the result.
You can perform the same transformation on each element in a collection. This allows you to look at the simpler problem of transforming a single item instead of a collection of items.
You can decompose a bigger problem of counting the number of lines in a file whose name you have into two smaller problems: opening a file, given its name; and counting the number of lines in a given file.
By using transform, you can create functions that can process collections of items from functions that can process only one item at a time.
Function composition and lifting can be compared to a moving assembly line. Different transformations work on single items. By lifting these transformations to work on collections of items and composing them so that the result of one transformation is passed on to the next transformation, you get an assembly line that applies a series of transformations to as many items as you want.
Summary
- The main philosophy of functional programming is that you shouldn’t concern yourself with the way something should work, but rather with what it should do.
- Both approaches—functional programming and object-oriented programming—have a lot to offer. You should know when to use one, when to use the other, and when to combine them.
- C++ is a multiparadigm programming language you can use to write programs in various styles—procedural, object-oriented, and functional—and combine those styles with generic programming.
- Functional programming goes hand-in-hand with generic programming, especially in C++. They both inspire programmers not to think at the hardware level, but to move higher.
- Function lifting lets you create functions that operate on collections of values from functions that operate only on single values. With function composition, you can pass a value through a chain of transformations, and each transformation passes its result to the next.
- Avoiding mutable state improves the correctness of code and removes the need for mutexes in multithreaded code.
- Thinking functionally means thinking about the input data and the transformations you need to perform to get the desired output.
Functional Programming in C++ ebook for free