Muutke küpsiste eelistusi

Functional Programming in C# 2nd edition [Pehme köide]

  • Formaat: Paperback / softback, 425 pages, kõrgus x laius x paksus: 232x190x20 mm, kaal: 150 g
  • Ilmumisaeg: 03-Mar-2022
  • Kirjastus: Manning Publications
  • ISBN-10: 1617299820
  • ISBN-13: 9781617299827
Teised raamatud teemal:
  • Formaat: Paperback / softback, 425 pages, kõrgus x laius x paksus: 232x190x20 mm, kaal: 150 g
  • Ilmumisaeg: 03-Mar-2022
  • Kirjastus: Manning Publications
  • ISBN-10: 1617299820
  • ISBN-13: 9781617299827
Teised raamatud teemal:
Real world examples and practical techniques for functional programming in C# without the jargon and theory.

In Functional Programming in C#, Second Edition you will learn how to:

    Use higher-order functions to reduce duplication and do more with less code
    Use pure functions to write code that is easy to test and optimize
    Write pleasant APIs that accurately describe your program's behavior
    Use dedicated types to handle nullability, system errors, and validation rules predictably and elegantly
    Write composable code without the overhead of an IoC container

Functional Programming in C# has helped thousands of developers apply functional thinking to C# code. Its practical examples and spot-on treatment of FP concepts makes it the perfect guide for proficient C# programmers. This second edition is fully revised to cover new functional-inspired features in the most recent releases of C#, including tuples, async streams, pattern matching, and records. Each chapter is packed with awesome perspectives and epiphany moments on how functional programming can change the way you code.

Purchase of the print book includes a free eBook in PDF, Kindle, and ePub formats from Manning Publications.

About the technology
Turbocharge your C# code. Good functional techniques will improve concurrency, state management, event handling, and maintainability of your software. This book gives you practical answers to why, how, and where to add functional programing into your C# coding practice.

About the book
Functional Programming in C#, Second Edition teaches functional thinking for real-world problems. It reviews the C# language features that allow you to program functionally and through many practical examples shows the power of function composition, data-driven programming, and immutable data structures. All code examples work with .NET 6 and C# 10.

What's inside

    Higher-order functions reduce duplication and do more with less code
    Code based on pure functions is easy to test and optimize
    Write pleasant APIs that accurately describe your program’s behavior
    Write a Web API in a functional style
    Monadic composition with LINQ

About the reader
For intermediate C# programmers.

About the author
Enrico Buonanno studied Computer Science at Columbia University and has over 15 years of experience as a developer, architect, and trainer.

Table of Contents
PART 1 GETTING STARTED
1 Introducing functional programming
2 Thinking in functions
3 Why function purity matters
PART 2 CORE TECHNIQUES
4 Designing function signatures and types
5 Modeling the possible absence of data
6 Patterns in functional programming
7 Designing programs with function composition
PART 3 FUNCTIONAL DESIGNS
8 Functional error handling
9 Structuring an application with functions
10 Working effectively with multi-argument functions
11 Representing state and change
12 A short introduction to functional data structures
13 Event sourcing: A functional approach to persistence
PART 4 ADVANCED TECHNIQUES
14 Lazy computations, continuations, and the beauty of monadic composition
15 Stateful programs and stateful computations
16 Working with asynchronous computations
17 Traversable and stacked monads
18 Data streams and the Reactive Extensions
19 An introduction to message-passing concurrency

Arvustused

A great book on becoming a master of Functional Programming.6 Najeeb Arif You have to read thisit'll give you a whole new perspective on things. Jedidja Bourgeois This is an extremely good presentation of functional concepts to C# developers. David Paccoud

Preface xv
Acknowledgments xvii
About This Book xviii
About The Author xxii
Part 1 Getting Started 1(58)
1 Introducing functional programming
3(16)
1.1 What is this thing called functional programming?
4(5)
Functions as first-class values
4(1)
Avoiding state mutation
5(1)
Writing programs with strong guarantees
6(3)
1.2 How functional a language is C#?
9(9)
The functional nature of LINQ
9(1)
Shorthand syntax for coding functionally
10(2)
Language support for tuples
12(2)
Pattern matching and record types
14(4)
1.3 What you will learn in this book
18(1)
2 Thinking in functions
19(14)
2.1 What's a function, anyway?
19(6)
Functions as maps
20(1)
Representing functions in C#
20(5)
2.2 Higher-order functions (HOFs)
25(4)
Functions that depend on other functions
25(2)
Adapter functions
27(1)
Functions that create other functions
28(1)
2.3 Using HOFs to avoid duplication
29(3)
Exercises
32(1)
3 Why function purity matters
33(26)
3.1 What is function purity?
34(3)
Purity and side effects
34(1)
Strategies for managing side effects
35(1)
Avoid mutating arguments
36(1)
3.2 Enabling parallelization by avoiding state mutation
37(7)
Pure functions parallelize well
39(1)
Parallelizing impure functions
40(2)
Avoiding state mutation
42(2)
3.3 Purity and testability
44(6)
Isolating I/O effects
44(2)
A business validation scenario
46(2)
Why testing impure functions is hard
48(2)
3.4 Testing code that performs I/O
50(7)
Object-oriented dependency injection
50(4)
Testability without so much boilerplate
54(3)
3.5 Purity and the evolution of computing
57(1)
Exercises
57(2)
Part 2 Core Techniques 59(78)
4 Designing function signatures and types
61(14)
4.1 Designing function signatures
62(2)
Writing functions signatures with arrow notation
62(1)
How informative is a signature?
63(1)
4.2 Capturing data with data objects
64(6)
Primitive types are often not specific enough
65(1)
Constraining inputs with custom types
65(2)
Writing honest functions
67(2)
Composing values into complex data objects
69(1)
4.3 Modeling the absence of data with Unit
70(5)
Why void isn't ideal
71(1)
Bridging the gap between Action and Func
72(3)
5 Modeling the possible absence of data
75(20)
5.1 The bad APIs you use every day
76(1)
5.2 An introduction to the Option type
77(2)
5.3 Implementing Option
79(5)
An idealized implementation of Option
79(1)
Consuming an Option
80(1)
Creating a None
81(1)
Creating a Some
82(1)
Optimizing the Option implementation
83(1)
5.4 Option as the natural result type of partial functions
84(4)
Parsing strings
85(1)
Looking up data in a collection
86(1)
The smart constructor pattern
87(1)
5.5 Dealing with null
88(6)
Why null is such a terrible idea
88(1)
Gaining robustness by using Option instead of null
89(1)
Non-nullable reference types?
90(2)
Bulletproof against NullReferenceException
92(2)
Exercises
94(1)
6 Patterns in functional programming
95(22)
6.1 Applying a function to a structure's inner values
96(5)
Mapping a function onto a sequence
96(1)
Mapping a function onto an Option
97(2)
How Option raises the level of abstraction
99(1)
Introducing functors
100(1)
6.2 Performing side effects with ForEach
101(2)
6.3 Chaining functions with Bind
103(5)
Combining Option-returning functions
104(1)
Flattening nested - lists with Bind
105(2)
Actually, it's called a monad
107(1)
The Return function
107(1)
Relationship between functors and monads
108(1)
6.4 Filtering values with Where
108(1)
6.5 Combining Option and IEnumerable with Bind
109(2)
6.6 Coding at different levels of abstraction
111(4)
Regular vs. elevated values
111(1)
Crossing levels of abstraction
112(2)
Map vs. Bind, revisited
114(1)
Working at the right level of abstraction
114(1)
Exercises
115(2)
7 Designing programs with function composition
117(20)
7.1 Function composition
118(3)
Brushing up on function composition
118(1)
Method chaining
119(1)
Composition in the elevated world
120(1)
7.2 Thinking in terms of data flow
121(4)
Using LINQ's composable API
121(2)
Writing functions that compose well
123(2)
7.3 Programming workflows
125(3)
A simple workflow for validation
125(1)
Refactoring with data flow in mind
126(1)
Composition leads to greater flexibility
127(1)
7.4 An introduction to functional domain modeling
128(2)
7.5 An end-to-end server-side workflow
130(5)
Expressions vs. statements
131(1)
Declarative vs. imperative
132(1)
The functional take on layering
133(2)
Exercises
135(2)
Part 3 Functional Designs 137(140)
8 Functional error handling
139(26)
8.1 A safer way to represent outcomes
140(6)
Capturing error details with Either
140(4)
Core functions for working with Either
144(1)
Comparing Option and Either
145(1)
8.2 Chaining operations that may fail
146(2)
8.3 Validation: A perfect use case for Either
148(3)
Choosing a suitable representation for errors
149(1)
Defining an Either-based API
150(1)
Adding validation logic
150(1)
8.4 Representing outcomes to client applications
151(5)
Exposing an Option-like interface
153(1)
Exposing an Either-like interface
154(1)
Returning a result DTO
155(1)
8.5 Variations on the Either theme
156(7)
Changing between different error representations
156(1)
Specialized versions of Either
157(1)
Refactoring to Validation and Exceptional
158(4)
Leaving exceptions behind?
162(1)
Exercises
163(2)
9 Structuring an application with functions
165(30)
9.1 Partial application: Supplying arguments piecemeal
166(5)
Manually enabling partial application
168(1)
Generalizing partial application
169(1)
Order of arguments matters
170(1)
9.2 Overcoming the quirks of method resolution
171(3)
9.3 Curried functions: Optimized for partial application
174(2)
9.4 Creating a partial-application-friendly API
176(4)
Types as documentation
177(1)
Particularizing the data access function
178(2)
9.5 Modularizing and composing an application
180(9)
Modularity in OOP
181(2)
Modularity in FP
183(3)
Mapping functions to API endpoints
186(2)
Comparing the two approaches
188(1)
9.6 Reducing a list to a single value
189(4)
LINQ's Aggregate method
189(2)
Aggregating validation results
191(1)
Harvesting validation errors
192(1)
Exercises
193(2)
10 Working effectively with multi-argument functions
195(26)
10.1 Function application in the elevated world
196(7)
Understanding applicatives
198(2)
Lifting functions
200(1)
An introduction to property-based testing
201(2)
10.2 Functors, applicatives, and monads
203(2)
10.3 The monad laws
205(3)
Right identity
205(1)
Left identity
206(1)
Associativity
207(1)
Using Bind with multi-argument functions
208(1)
10.4 Improving readability by using LINQ with any monad
208(7)
Using LINQ with arbitrary functors
209(1)
Using LINQ with arbitrary monads
210(4)
The LINQ clauses let, where, and others
214(1)
10.5 When to use Bind vs. Apply
215(4)
Validation with smart constructors
215(1)
Harvesting errors with the applicative flow
216(2)
Failing fast with the monadic flow
218(1)
Exercises
219(2)
11 Representing state and change
221(18)
11.1 The pitfalls of state mutation
222(3)
11.2 Understanding state, identity, and change
225(4)
Some things never change
226(2)
Representing change without mutation
228(1)
11.3 Using records to capture the state of domain entities
229(6)
Fine-grained control on record initialization
231(2)
Immutable all the way down
233(2)
11.4 Separating data and logic
235(4)
12 A short introduction to functional data structures
239(13)
12.1 The classic functional linked list
240(6)
Common list operations
243(1)
Modifying an immutable list
244(1)
Destructuring any IEnumerable
245(1)
12.2 Binary trees
246(4)
Common tree operations
247(2)
Structure sharing
249(1)
12.3 In conclusion
250(1)
Exercises
250(2)
13 Event sourcing: A functional approach to persistence
252(25)
13.1 Thinking functionally about data storage
253(2)
Why data storage should be append-only
253(1)
Relax and forget about storing state
254(1)
13.2 Event sourcing basics
255(7)
Representing events
256(1)
Persisting events
257(1)
Representing state
258(1)
Representing state transitions
258(2)
Reconstructing the current state from past events
260(2)
13.3 Architecture of an event-sourced system
262(10)
Handling commands
263(3)
Handling events
266(1)
Adding validation
267(2)
Creating views of the data from events
269(3)
13.4 Comparing different approaches to immutable storage
272(7)
Datomic vs. Event Store
273(1)
How event-driven is your domain?
273(4)
Part 4 Advanced Techniques 277(124)
14 Lazy computations, continuations, and the beauty of monadic composition
279(23)
14.1 The virtue of laziness
280(5)
Lazy APIs for working with Option
281(2)
Composing lazy computations
283(2)
14.2 Exception handling with Try
285(6)
Representing computations that may fail
286(1)
Safely extracting information from a JSON object
287(1)
Composing computations that may fail
288(1)
Monadic composition: What does it mean?
289(2)
14.3 Creating a middleware pipeline for DB access
291(11)
Composing functions that perform setup/teardown
291(2)
A recipe against the pyramid of doom
293(1)
Capturing the essence of a middleware function
293(2)
Implementing the query pattern for middleware
295(3)
Adding middleware that times the operation
298(1)
Adding middleware that manages a DB transaction
299(3)
15 Stateful programs and stateful computations
302(16)
15.1 Programs that manage state
303(6)
Caching data in memory
304(2)
Refactoring for testability and error handling
306(2)
Stateful computations
308(1)
15.2 A language for generating random data
309(5)
Generating random integers
310(1)
Generating other primitives
310(2)
Generating complex structures
312(2)
15.3 A general pattern for stateful computations
314(4)
16 Working with asynchronous computations
318(18)
16.1 Asynchronous computations
319(11)
The need for asynchrony
319(1)
Representing asynchronous operations with Task
320(2)
Task as a container for a future value
322(2)
Handling failure
324(2)
An HTTP API for currency conversion
326(1)
If it fails, try a few more times
327(1)
Running asynchronous operations in parallel
328(2)
16.2 Async streams
330(6)
Reading from a file as an async stream
331(2)
Consuming async streams functionally
333(1)
Consuming data from several streams
333(1)
Aggregation and sorting with async streams
334(2)
17 Traversable and stacked monads
336(15)
17.1 Traversables: Working with lists of elevated values
336(9)
Validating a list of values with monadic Traverse
338(1)
Harvesting validation errors with applicative Traverse
339(2)
Applying multiple validators to a single value
341(1)
Using Traverse with Task to await multiple results
342(2)
Defining Traverse for single-value structures
344(1)
17.2 Combining asynchrony and validation (or any other two monadic effects)
345(6)
The problem of stacked monads
345(2)
Reducing the number of effects
347(1)
LINQ expressions with a monad stack
348(3)
18 Data streams and the Reactive Extensions
351(25)
18.1 Representing data streams with IObservable
352(3)
A sequence of values in time
353(1)
Subscribing to an IObservable
354(1)
18.2 Creating IObservables
355(5)
Creating a timer
356(1)
Using Subject to tell an IObservable when it should signal
357(1)
Creating IObservables from callback-based subscriptions
358(1)
Creating lObservables from simpler structures
359(1)
18.3 Transforming and combining data streams
360(6)
Stream transformations
360(2)
Combining and partitioning streams
362(2)
Error handling with IObservable
364(2)
Putting it all together
366(1)
18.4 Implementing logic that spans multiple events
366(8)
Detecting sequences of pressed keys
367(2)
Reacting to multiple event sources
369(2)
Notifying when an account becomes overdrawn
371(3)
18.5 When should you use IObservable?
374(2)
19 An introduction to message-passing concurrency
376(25)
19.1 The need for shared mutable state
377(1)
19.2 Understanding message-passing concurrency
378(11)
Implementing agents in C#
381(1)
Getting started with agents
382(2)
Using agents to handle concurrent requests
384(3)
Agents vs. actors
387(2)
19.3 Functional APIs, agent-based implementations
389(3)
Agents as implementation details
390(1)
Hiding agents behind a conventional API
391(1)
19.4 Message-passing concurrency in LOB applications
392(9)
Using an agent to synchronize access to account data
393(1)
Keeping a registry of accounts
394(1)
An agent is not an object
395(3)
Putting it all together
398(3)
Appendix A Working with previous version of C# 401(12)
Epilogue What next? 413(2)
Index 415
Enrico Buonanno studied computer science at Columbia University and hasover 15 years of experience as a developer, architect, and trainer.