Overview

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.
c01_01.png
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.
c01_02.png
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.
c01_03.png
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.
c01_04.png
When thinking functionally, you consider the transformations you need to apply to the given input to get the desired output as the result.
c01_05.png
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.
c01_06.png
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.
c01_07.png
By using transform, you can create functions that can process collections of items from functions that can process only one item at a time.
c01_08.png
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.
c01_09.png

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.

FAQ

What is functional programming (FP) and how is it framed in this chapter?FP is a style of programming that emphasizes evaluating expressions and composing functions to describe what a result is, rather than prescribing step-by-step commands. In this chapter, FP is presented as a way to write concise, composable, and safer C++ code by focusing on intent and transformations.
How does declarative (functional) code differ from imperative code?Imperative code specifies how to compute a result through explicit steps and state updates. Declarative/functional code states what the result is and relies on function composition and library abstractions to perform the work, reducing boilerplate and mutable state.
What are pure functions and why are they important?Pure functions always return the same output for the same inputs and have no observable side effects. They reduce coupling through shared state, make code easier to reason about and test, and enable safe composition and parallelization.
Do pure functions forbid I/O and all state changes?In practice, purity is defined by the absence of observable side effects at the caller’s level. While machine state changes inevitably occur, we strive to keep observable side effects at the boundaries and keep most functions pure-looking to callers.
How does FP help with concurrency and synchronization?Because pure functions don’t mutate shared state, they can be executed in parallel without locks or atomics. Algorithms like sum or transform can split work across threads safely when their operations are pure.
What does “thinking functionally” mean when approaching a problem?Identify inputs and desired outputs, then design a pipeline of small, focused transformations. Solve the problem for a single item (e.g., a single file) and lift that solution to collections (e.g., a list of files) using tools like std::transform or ranges.
What is “lifting,” and how does std::transform relate to it?Lifting takes a function that operates on a single value and adapts it to operate over a structure (like a collection). std::transform is a lifting tool: it applies a per-item function across an entire range and collects the results.
Why are ranges considered more readable than raw STL algorithms in this context?Ranges let you express intent as a pipeline (e.g., files | transform(open_file) | transform(count_lines)), keeping just the essential parts—input, transformations, and result—while removing iterator boilerplate.
How does functional programming relate to object-oriented programming in C++?They are complementary. OOP abstracts data and behavior behind types; FP abstracts control flow and transformation via functions. Many C++ programs benefit from mixing both paradigms, and the language supports this multiparadigm style.
Which C++ features enable functional programming, and how has the language evolved?Templates and the STL algorithms established early FP-style capabilities. Modern C++ adds lambdas, auto, enhanced algorithms, and (with newer standards) ranges, concepts, and coroutines—making functional, declarative code more expressive and practical.

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Functional Programming in C++ ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Functional Programming in C++ ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Functional Programming in C++ ebook for free