Functional programming is a way of thinking about programs that emphasizes functions, while avoiding state mutation. It allows us to write elegant, intention-revealing code, that shines in testability and support for concurrency. C# includes a number of functional features and libraries, enabling us to take advantage of these benefits.
Functional Programming in C# teaches you to apply functional thinking to real-world scenarios. You’ll start by learning the principles of functional programming, and how they translate in the C# language. The book then dives into important topics like function composition, data flow, and principles for designing function signatures, types and collections. Through lots of real-world examples, you’ll acquire the tools to tackle programming tasks with a functional approach. The last part of the book deals with advanced topics, including lazy evaluation, stateful computations, asynchrony, and event streams. By the end of this book, you’ll be able to integrate functional techniques, making your C# programs robust and maintainable, and helping you become a more well-rounded developer.
Author(s): Enrico Buonanno
Publisher: Manning
Year: 2017
Language: English
Pages: 408
Dedication
About this Book
Who should read this book
How this book is organized
Code conventions and downloads
Book forum
About the author
Part 1. Core concepts
Chapter 1. Introducing functional programming
1.1. What is this thing called functional programming?
1.2. How functional a language is C#?
1.3. Thinking in functions
1.4. Higher-order functions
1.5. Using HOFs to avoid duplication
1.6. Benefits of functional programming
Chapter 2. Why function purity matters
2.1. What is function purity?
2.2. Purity and concurrency
2.3. Purity and testability
2.4. Purity and the evolution of computing
Chapter 3. Designing function signatures and types
3.1. Function signature design
3.2. Capturing data with data objects
3.3. Modeling the absence of data with Unit
3.4. Modeling the possible absence of data with Option
Chapter 4. Patterns in functional programming
4.1. Applying a function to a structure’s inner values
4.2. Performing side effects with ForEach
4.3. Chaining functions with Bind
4.4. Filtering values with Where
4.5. Combining Option and IEnumerable with Bind
4.6. Coding at different levels of abstraction
Chapter 5. Designing programs with function composition
5.1. Function composition
5.2. Thinking in terms of data flow
5.3. Programming workflows
5.4. An introduction to functional domain modeling
5.5. An end-to-end server-side workflow
Part 2. Becoming functional
Chapter 6. Functional error handling
6.1. A safer way to represent outcomes
6.2. Chaining operations that may fail
6.3. Validation: a perfect use case for Either
6.4. Representing outcomes to client applications
6.5. Variations on the Either theme
Chapter 7. Structuring an application with functions
7.1. Partial application: supplying arguments piecemeal
7.2. Overcoming the quirks of method resolution
7.3. Curried functions: optimized for partial application
7.4. Creating a partial-application-friendly API
7.5. Modularizing and composing an application
7.6. Reducing a list to a single value
Chapter 8. Working effectively with multi-argument functions
8.1. Function application in the elevated world
8.2. Functors, applicatives, monads
8.3. The monad laws
8.4. Improving readability by using LINQ with any monad
8.5. When to use Bind vs. Apply
Chapter 9. Thinking about data functionally
9.1. The pitfalls of state mutation
9.2. Understanding state, identity, and change
9.3. Enforcing immutability
9.4. A short introduction to functional data structures
Chapter 10. Event sourcing: a functional approach to persistence
10.1. Thinking functionally about data storage
10.2. Event sourcing basics
10.3. Architecture of an event-sourced system
10.4. Comparing different approaches to immutable storage
Part 3. Advanced techniques
Chapter 11. Lazy computations, continuations, and the beauty of monadic composition
11.1. The virtue of laziness
11.2. Exception handling with Try
11.3. Creating a middleware pipeline for DB access
Summary
Chapter 12. Stateful programs and stateful computations
12.1. Programs that manage state
12.2. A language for generating random data
12.3. A general pattern for stateful computations
Summary
Chapter 13. Working with asynchronous computations
13.1. Asynchronous computations
13.2. Traversables: working with lists of elevated values
13.3. Combining asynchrony and validation (or any other two monadic effects)
Summary
Chapter 14. Data streams and the Reactive Extensions
14.1. Representing data streams with IObservable
14.2. Creating IObservables
14.3. Transforming and combining data streams
14.4. Implementing logic that spans multiple events
14.5. When should you use IObservable?
Summary
Chapter 15. An introduction to message-passing concurrency
15.1. The need for shared mutable state
15.2. Understanding message-passing concurrency
15.3. Functional APIs, agent-based implementations
15.4. Message-passing concurrency in LOB applications
Summary
Inverted chapter dependency graph