Functional Programming in C#
Enrico Buonanno
  • MEAP began May 2016
  • Publication in March 2017 (estimated)
  • ISBN 9781617293955
  • 325 pages (estimated)
  • printed in black & white

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.

"Amazing book for people who know C# and are looking to learn more as well as people who are interested in being more productive and improving their programing skills. Seriously, I can't wait to get my copy."

~ Gonzalo Barba Lopez

"If you are wanting to dip your toes into functional programming, learn techniques for applying FP in C#, or just want to be a better programmer, you should read this. "

~ Devon Burriss

Table of Contents detailed table of contents

1. Introducing functional programming

1.1. What is this thing called functional programming?

1.1.1. Functions as 1st-class values

1.1.2. Avoiding state mutation

1.1.3. Writing programs with strong guarantees

1.2. How functional a language is C#?

1.2.1. The functional nature of LINQ

1.2.2. Functional features in C#6

1.2.3. A more Functional features in C#7

1.3. Thinking in functions

1.3.1. Functions as maps

1.3.2. Representing functions in C#

1.4. Higher-order functions

1.4.1. Functions that depend on other functions

1.4.2. Adapter functions

1.4.3. Function factories

1.5. In practice: avoiding duplication with HOFs

1.5.1. Encapsulating setup and teardown into a HOF

1.5.2. Turning the using statement into a HOF

1.5.3. Code review: tradeoffs of HOFs

1.6. Benefits of functional programming

1.7. Summary

1.8. Exercises

2. Why function purity matters

2.1. What is function purity?

2.1.1. Purity and side effects

2.1.2. Strategies for managing side effects

2.2. Purity and concurrency

2.2.1. Pure functions parallelize well

2.2.2. Parallelizing impure functions

2.2.3. Avoiding state mutation

2.3. Purity and Testability

====In practice: a validation scenario ==== Bringing impure functions under test ==== Why testing impure functions is hard ==== Parameterized unit tests ==== Avoiding header interfaces === Purity in the context of changes in computing === Exercises === Summary

3. Designing function signatures and types

3.1. Function signature design

3.1.1. Arrow notation

3.1.2. How informative is a signature?

3.2. Capturing data with data objects

3.2.1. Primitive types are often not specific enough

3.2.2. Constraining inputs with custom types

3.2.3. Writing "honest" functions

3.2.4. Composing values with tuples and objects

3.3. Modelling the absence of data with Unit

3.3.1. Why using void is not ideal

3.3.2. Bridging the gap between Action and Func with Unit

3.4. Modelling the possible absence of data with Option

3.4.1. The bad APIs you use every day

3.4.2. An introduction to the Option type

3.4.3. Implementing Option

3.4.4. Gaining robustness by using Option instead of null

3.4.5. Option as the natural result type of partial functions

3.5. Exercises

3.6. Summary

4. Patterns in Functional Programming

4.1. Applying a function to the inner values of a structure

4.1.1. Mapping a function onto a sequence of values

4.1.2. Mapping a function onto an optional value

4.1.3. Introducing Functors

4.2. Performing side effects with ForEach

4.3. The Bind function

4.3.1. Composing Option-returning functions with Bind

4.4. Flattening nested lists with Bind

4.4.1. Actually, it's called a monad

4.4.2. The Return function

4.4.3. Relation between functors and monads

4.5. Filtering values with Where

4.6. Combining Option and IEnumerable with Bind

4.7. Coding at different levels of abstraction

4.7.1. Regular vs elevated values

4.7.2. Crossing levels of abstraction

4.7.3. Map vs Bind, revisited

4.7.4. Working at the right level of abstraction

4.8. Exercises

4.9. Summary

5. Designing programs with function composition

5.1. Function composition

5.1.1. Brushing up on function composition

5.1.2. Method chaining

5.1.3. Composition in the elevated world

5.2. Thinking in terms of data flow

5.2.1. Using LINQ's composable API

5.2.2. Writing functions that compose well

5.3. Programming workflows

5.3.1. A simple workflow for validation

5.3.2. Refactoring with data flow in mind

5.3.3. Composition leads to greater flexibility

5.4. An introduction to functional domain modelling

5.5. An end-to-end server-side workflow

5.5.1. Expressions vs statements

5.5.2. Declarative vs imperative

5.5.3. The functional take on layering

5.6. Exercises

5.7. Summary

6. Functional error handling

6.1. A safer way to represent outcomes

6.1.1. Capturing error details with Either

6.1.2. Core functions for working with Either

6.1.3. Comparing Option and Either

6.2. Chaining operations that may fail

6.3. Validation: a perfect use case for Either

6.3.1. Choosing a suitable representation for errors

6.3.2. Defining an Either-based API

6.3.3. Adding validation logic

6.3.4. Modularizing validation

6.4. Reducing a list to a single value

6.4.1. LINQ’s Aggregate method

6.4.2. Aggregating validation results

6.5. Different validation strategies

6.5.1. Failing fast

6.5.2. Aggregating validation errors

6.6. Representing outcomes to client applications

6.6.1. Exposing an Option-like interface

6.6.2. Exposing an Either-like interface

6.6.3. Returning a result DTO

6.7. Virtues and shortcomings of Either

6.7.1. Specialized versions of Either

6.7.2. Refactoring to Validation and Exceptional

6.7.3. Leaving exceptions behind

6.8. Exercises

6.9. Summary

7. The power of partial application

7.1. What is partial application?

7.1.1. Manually enabling partial application

7.1.2. Generalizing partial application

7.1.3. Order of arguments matters

7.2. Overcoming the quirks of method resolution

7.3. Creating a partial-application-friendly API

7.3.1. Types as documentation

7.3.2. Particularizing the data access function

7.4. Composing an application with functions

7.4.1. Parameterizing functions

7.4.2. Functions that depend on other functions

7.4.3. Decoupling and testability in the functional approach

7.4.4. Dependency injection via partial application

7.5. Currying

7.6. Summary

7.7. Exercises

8. Working effectively with multi-argument functions

8.1. Function application in the elevated world

8.1.1. Understanding applicatives

8.1.2. Lifting functions

8.1.3. An introduction to property testing

8.2. Functors, Applicatives, Monads

8.3. The monad laws

8.3.1. Right identity

8.3.2. Left identity

8.3.3. Associativity

8.3.4. Using Bind with multi-argument functions

8.4. Improving readability by using LINQ with any monad

8.4.1. Using LINQ with arbitrary functors

8.4.2. Using LINQ with arbitrary monads

8.4.3. Let, Where and other LINQ clauses

8.5. In practice: when to use Bind vs. Apply

8.5.1. Validation with smart constructors

8.5.2. The applicative flow

8.5.3. The monadic flow

8.6. Exercises

8.7. Summary

9. Thinking about data functionally

9.1. The pitfalls of state mutation

9.2. Understanding state, identity, and change

9.2.1. Some things never change

9.2.2. Representing change without mutation

9.2.3. Enforcing immutability

9.2.4. Leveraging F# for data types

9.3. A short introduction to functional data structures

9.3.1. The classic functional linked list

9.3.2. Binary trees

9.4. Summary

9.5. Exercises

10. Event sourcing: a functional approach to data persistence

10.1. Thinking functionally about data storage

10.1.1. Why data storage should be append-only

10.1.2. Relax, and forget about storing state

10.2. Event sourcing basics

10.2.1. Representing events

10.2.2. Persisting events

10.2.3. Representing state

10.2.4. An interlude on pattern matching

10.2.5. Representing state transitions

10.2.6. Reconstructing current state from past events

10.3. Architecture of an event sourced system

10.3.1. Handling commands

10.3.2. Handling events

10.3.3. Adding validation

10.3.4. Creating views of the data from events

10.4. Comparing different approaches to immutable storage

10.4.1. Datomic vs Event Store

10.4.2. How event-driven is your domain?

10.5. Summary

11. Lazy computations, stateful computations, and other composable gems

12. Working with asynchronous values and data streams

13. Radically improving testability with free monads (tentative)

14. A functional approach to soncurrency (tentative)

What's inside

  • Introduction to functional programming and design
  • Explore C#'s functional programming capabilities
  • Understand how function purity improves testability and support for concurrency
  • Write more readable, declarative code by writing functions that compose
  • Adopt a new approach to error handling and managing state
  • Embrace event-driven design and immutability
  • Leverage concurrency without the pitfalls of shared mutable state
  • Apply functional programming to solve real-world problems

About the reader

This book is designed to help C# programmers with an OOP background understand functional thinking.

About the author

Enrico Buonanno obtained an MS in Computer Science at Columbia University in 2001 and has been working as a software developer and architect since. Working on mission-critical applications in FinTech and other technology-driven businesses has given him a thorough understanding of the demands made on enterprise applications, and how to respond to them with modern designs and techniques.


Manning Early Access Program (MEAP) Read chapters as they are written, get the finished eBook as soon as it’s ready, and receive the pBook long before it's in bookstores.
Buy
  • MEAP combo $49,99 pBook + eBook
  • MEAP eBook $39,99 pdf + ePub + kindle

FREE domestic shipping on three or more pBooks