Discover millions of audiobooks, ebooks, and so much more with a free trial

From $11.99/month after trial. Cancel anytime.

Functional Programming with C#: Unlock coding brilliance with the power of functional magic
Functional Programming with C#: Unlock coding brilliance with the power of functional magic
Functional Programming with C#: Unlock coding brilliance with the power of functional magic
Ebook612 pages3 hours

Functional Programming with C#: Unlock coding brilliance with the power of functional magic

Rating: 0 out of 5 stars

()

Read preview
LanguageEnglish
Release dateJul 31, 2024
ISBN9781805128939
Functional Programming with C#: Unlock coding brilliance with the power of functional magic

Related to Functional Programming with C#

Related ebooks

Programming For You

View More

Reviews for Functional Programming with C#

Rating: 0 out of 5 stars
0 ratings

0 ratings0 reviews

What did you think?

Tap to rate

Review must be at least 10 words

    Book preview

    Functional Programming with C# - Alex Yagur

    Cover.png

    Functional Programming with C#

    Copyright © 2024 Packt Publishing

    All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

    Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.

    Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

    Group Product Manager: Kunal Sawant

    Assistant Publishing Product Manager: Debadrita Chatterjee

    Book Project Manager: Manisha Singh

    Senior Editor: Kinnari Chohan

    Technical Editor: Vidhisha Patidar

    Copy Editor: Safis Editing

    Proofreader: Kinnari Chohan

    Indexer: Pratik Shirodkar

    Production Designer: Prashant Ghare

    DevRel Marketing Coordinator: Sonia Chauhan

    First published: July 2024

    Production reference: 1110724

    Published by Packt Publishing Ltd.

    Grosvenor House

    11 St Paul’s Square

    Birmingham

    B3 1RB, UK

    ISBN 978-1-80512-268-5

    www.packtpub.com

    To Julia, my beloved wife and steadfast companion on this journey.

    To my parents, whose unwavering support and guidance have shaped me into who I am today.

    To my daughters, Irina, Lisa, and Emily - you are my inspiration and my greatest joy. May this work inspire you to pursue your dreams with passion and perseverance.

    Contributors

    About the author

    Alex Yagur has been working in software development since 2000, specializing in C#. He holds Master’s degrees in Software Development and Organizational Management. Alex has created multiple online courses for software developers and is the founder of Hands-On Dev Academy, an educational platform that uses practice-focused approaches, AI, and gamification to enhance the online learning experience. His interests include computer games, mountaineering, running, and diving. Alex is dedicated to improving software education and making complex concepts accessible to learners worldwide.

    I would like to express my heartfelt gratitude to:

    Logan Ferris for keeping me fit and energized throughout this project.

    Konstantin Rochev and Andrew Pasenchuk for their meticulous review of this book.

    Kinnari Chohan and Manisha Singh for their guidance throughout the writing process.

    My students, who have taught me so much while I’ve been teaching them.

    Your help and support made this book possible.

    Thank you.

    About the reviewers

    Lucas Venturella started programming because it was the most amazing thing he discovered while growing up. Over the years, he has experienced many changes. Initially driven by passion, his primary motivation today is his daughter and family. The desire to positively impact the world for future generations, especially his child’s, is what truly drives him now. He believes that being completely dedicated to something to the point where one can influence the world is a crucial skill, and he hopes to impart this to his child. Lucas’s main skills today include .NET, DevOps, and some frontend development.

    Andrey Pasenchuk is a software architect with expertise in designing high-loaded systems. With a strong background in computer science and mathematics, along with more than a decade of experience, he has successfully developed scalable and efficient solutions. His primary focus is on crafting architectures that align perfectly with the product, ensuring ease of maintenance and cost-effective scalability. Andrei is committed to continuously improving his skills and exploring new technologies to remain at the forefront of system architecture.

    Table of Contents

    Preface

    Part 1: Foundations of Functional Programming in C#

    1

    Getting Started with Functional Programming

    Functional versus imperative versus object-oriented programming

    Imperative programming

    Object-oriented programming

    Functional programming

    Blending paradigms

    How functional programming is supported in C#

    How to write functional code in C#

    A practical example – a book publishing system

    How to combine functional and object-oriented paradigms

    Meet Steve and Julia

    Summary

    2

    Expressions and Statements

    Task 1 – Name and count all expressions and all statements

    Task 2 – Use expressions instead of statements

    Task 3 – Create an expression tree

    Understanding the difference between expressions and statements

    Example of expressions

    Example of statements

    Key differences between expressions and statements

    Guided exercise – finding expressions and statements in sample code

    How to use expressions for clear and simple code

    The power of expressions – improving readability and maintainability

    Techniques to convert statements to expressions

    Guided exercise – refactoring code using expressions

    Lambda expressions, expression-bodied members, and anonymous methods

    What are lambda expressions?

    Multiple parameters in lambda expressions

    Lambda expressions evolution

    Understanding anonymous methods

    How do anonymous methods work?

    When to use anonymous methods

    Practical examples – applying these features in real code

    Expression-bodied members

    Exercise – implementing lambda expressions and anonymous methods

    Expression trees and how to use them to manipulate expressions at runtime

    Building and manipulating expression trees

    Creating and manipulating complex expression trees

    Querying data with expression trees – LINQ and beyond

    Guided exercise – constructing and manipulating expression trees

    Problem sets and exercises

    Exercises

    Exercise 1

    Exercise 2

    Exercise 3

    Solutions

    Exercise 1

    Exercise 2

    Exercise 3

    Summary

    3

    Pure Functions and Side Effects

    Task 1 – Refactoring to a pure function

    Task 2 – Isolating side effects

    Task 3 – Using a Pure attribute

    Understanding pure functions

    Examples of pure functions

    The benefits of pure functions

    Comparisons of pure functions and non-pure functions

    Side effects

    Common sources of side effects

    Consequences of side effects

    Strategies to minimize side effects

    Favor immutability

    Use readonly and const

    Use functional programming principles

    Encapsulate side effects

    Marking pure functions with the Pure attribute

    Understanding the Pure attribute in C#

    The benefits of marking functions as pure

    Caveats and considerations when using the Pure attribute

    Exercises

    Exercise 1

    Exercise 2

    Exercise 3

    Solutions

    Exercise 1

    Exercise 2

    Exercise 3

    Summary

    4

    Honest Functions, Null, and Option

    Task 1 – Refactor for honest return types

    Task 2 – Guard against null inputs

    Task 3 – Pattern matching with nullable types

    Honest functions – definition and understanding

    The problems with hidden nulls

    A quick look back – C# and null

    Common mistakes and the troubling NullReferenceException

    Not all bad – the value of null

    Embracing honesty with nullable reference types

    What are nullable reference types?

    Transitioning to NRTs

    Enabling nullable reference types

    Disabling nullable reference types

    Warnings and annotations options

    The bigger picture – project-wide settings

    Returning with intention

    The distinction between UserProfile and UserProfile?

    Honoring a function’s contract

    Demanding honesty from function inputs

    Nullable reference types to the rescue

    Using preconditions and contracts

    Using built-in checks

    The power of explicit non-null inputs

    Pattern matching and nullable types

    Pattern matching with nullable types

    Switch expressions with property patterns

    Ensuring clarity with nullable types

    The null object pattern

    The problem with null checks

    The null object solution

    Advantages

    Limitations and considerations

    Beyond null – using Option

    A brief introduction to Option

    Advantages of the Option type over nullable types

    The interplay of Option and nullable types

    Practical scenarios – handling nulls effectively

    Case study – managing YouTube videos

    Case study – managing different video types

    Case study – working with non-existing objects

    The impact of handling nulls in real-world scenarios

    The reality of honesty in C# – why there will never be truly honest functions

    The compromises of the C# language design

    Practical tips and best practices

    Strategies for migrating existing code bases to adopt nullable reference types and Option

    Common pitfalls and how to navigate them

    Testing strategies for null and Option handling

    Exercises

    Exercise 1

    Exercise 2

    Exercise 3

    Solutions

    Exercise 1

    Exercise 2

    Exercise 3

    Summary

    Part 2: Advanced Functional Techniques

    5

    Error Handling

    Task 1 – Custom error types and result usage

    Task 2 – Utilizing ROP for validation and processing

    Task 3 – Implementing a Retry mechanism using functional techniques

    Traditional error handling in C#

    try-catch blocks

    Exceptions

    The Result type

    Implementing the Result type

    Using the Result type

    Railway-Oriented Programming (ROP)

    The essence of Bind

    Chaining operations with Bind

    Composable error handling with ROP

    Handling diverse error types

    Benefits of isolation

    Extending ROP for asynchronous operations

    Designing your own error-handling mechanisms

    Use factory methods for creation

    Extend with Bind

    Customize error types

    Leverage extension methods

    Integration with existing code

    Always iterate and refine

    Practical tips for functional error handling

    Avoid null with options

    Logging errors

    Two strategies To replace exceptions

    Anticipate errors – make it predictable

    Embrace composition

    Educate your team

    Traditional versus functional error handling comparison

    The traditional way

    The functional way

    Comparative analysis

    Making the shift

    Patterns and anti-patterns in functional error handling

    Exercises

    Exercise 1

    Exercise 2

    Exercise 3

    Solutions

    Exercise 1

    Exercise 2

    Exercise 3

    Summary

    6

    Higher-Order Functions and Delegates

    Task 1 – Sorting function

    Task 2 – Customized calculations

    Task 3 – Comparison

    Understanding higher-order functions

    The power of higher-order functions in functional programming

    Creating versatile code with fewer errors

    Supporting a more declarative coding style

    Delegates, actions, funcs, and predicates

    Delegates

    Actions

    Funcs

    Predicates

    Callbacks, events, and anonymous methods

    The role of delegates in events

    Delegates and anonymous methods

    Harnessing LINQ methods as higher-order functions

    Filtering

    Data transformation

    Data aggregation

    Case study – putting it all together

    Step-by-step walk-through and analysis of the code

    Best practices and common pitfalls

    Exercises

    Exercise 1

    Exercise 2

    Exercise 3

    Solutions

    Exercise 1

    Exercise 2

    Exercise 3

    Summary

    7

    Functors and Monads

    Task 1 – Functor usage

    Task 2 – Applicative functor

    Task 3 – Monad usage

    What’s a functor?

    Identity law

    Composition law

    Creating our own functor

    Functor benefits

    Applicative functors

    The Apply method implementation

    Applicative functor laws

    Monads

    The Bind method

    Monad laws

    Utilizing monads

    Key takeaways

    Exercises

    Exercise 1

    Exercise 2

    Exercise 3

    Solutions

    Exercise 1

    Exercise 2

    Exercise 3

    Summary

    Part 3: Practical Functional Programming

    8

    Recursion and Tail Calls

    Task 1 – Recursive enemy count

    Task 2 – Wave generation

    Task 3 – Asynchronously updating enemy stats

    Introducing recursion

    Recursive thinking

    Types of recursion

    Simple recursion

    Tail recursion

    Challenges of recursion

    Stack overflow risk

    Default stack size and limitations

    Performance considerations

    Leveraging C# features for recursion

    Local functions

    Pattern matching

    Advanced recursive patterns

    Mutual recursion

    Memoization

    Comparison with iterative solutions

    Readability

    Performance

    Recursion in asynchronous programming

    Explaining asynchronous recursion under the hood

    Synchronous versus asynchronous recursion

    Scenarios for asynchronous recursion

    Exercises

    Exercise 1

    Exercise 2

    Exercise 3

    Solutions

    Exercise 1

    Exercise 2

    Exercise 3

    Summary

    9

    Currying and Partial Application

    Task 1 – Currying tower attack functions

    Task 2 – Partial application for game settings

    Task 3 – Currying permission checks for game features

    Understanding currying

    Standard approach

    Curried approach

    Step-by-step implementation of currying

    Use cases

    Configuration settings

    Event handling

    Partial application

    Asynchronous programming

    Partial application

    Areas for partial application

    Example of partially applying a function for configuration settings

    Standard rendering function

    Partially applied function

    Challenges and limitations

    Exercises

    Exercise 1

    Exercise 2

    Exercise 3

    Solutions

    Solution 1

    Solution 2

    Solution 3

    Summary

    10

    Pipelines and Composition

    Task 1 – Enemy wave processing pipeline

    Task 2 – Game data file processing

    Task 3 – Dynamic SQL query generation using currying and partial application

    Function composition

    Building pipelines

    Performance considerations

    The fluent interface

    Advanced composition with monads

    Exercises

    Exercise 1

    Exercise 2

    Exercise 3

    Solutions

    Solution 1

    Solution 2

    Solution 3

    Summary

    Part 4: Conclusion and Future Directions

    11

    Reflecting and Looking Ahead

    A summary of the main concepts and techniques

    Comparison with other languages

    Resources for further learning

    Closing thoughts

    Index

    Other Books You May Enjoy

    Preface

    Welcome to Functional Programming with C#!

    This book is designed to introduce you to the powerful paradigm of functional programming within the context of C#. As C# continues to evolve, it increasingly embraces functional programming concepts, allowing developers to write more concise, maintainable, and robust code. This book will guide you through the journey of understanding and applying functional programming principles in C#, from basic concepts to advanced techniques.

    Who this book is for

    This book is aimed at C# developers who want to expand their programming toolkit by learning functional programming techniques. It’s suitable for intermediate to advanced programmers familiar with object-oriented programming and looking to enhance their skills. While prior knowledge of functional programming is not required, a solid understanding of C# fundamentals is necessary to get the most out of this book.

    What this book covers

    Chapter 1

    , Getting Started with Functional Programming, introduces the core concepts of functional programming and how they apply to C#.

    Chapter 2

    , Expressions and Statements, delves into the differences between expressions and statements, and how to write more expressive code.

    Chapter 3

    , Pure Functions and Side Effects, explores the concept of pure functions and how to minimize side effects in your code.

    Chapter 4

    , Honest Functions, Null, and Option, discusses the importance of honest functions and how to handle null values effectively.

    Chapter 5

    , Error Handling, introduces functional approaches to error handling, moving beyond traditional try-catch blocks.

    Chapter 6

    , Higher-Order Functions and Delegates, covers the power of functions as first-class citizens in C#.

    Chapter 7

    , Functors and Monads, explores these advanced functional programming concepts and their implementation in C#.

    Chapter 8

    , Recursion and Tail Calls, dives into recursive programming techniques and optimization.

    Chapter 9

    , Currying and Partial Application, teaches how to create more flexible and reusable functions.

    Chapter 10

    , Pipelines and Composition, shows how to combine functions to create powerful data processing pipelines.

    Chapter 11

    , Reflecting and Looking Ahead, summarizes the key concepts learned throughout the book and provides guidance on further advancing your functional programming skills in C#.

    To get the most out of this book

    To fully benefit from this book, readers should have a good grasp of C# basics, including object-oriented programming concepts. Familiarity with LINQ is helpful but not required. Each chapter builds upon the previous ones, so it’s recommended to read the book sequentially. Practice exercises are provided to reinforce the concepts learned.

    To follow along with the examples in this book, you’ll need to have the .NET 8 SDK installed on your machine. Visual Studio 2022 or Visual Studio Code with the C# extension are recommended for the best development experience. All code samples in the book are compatible with C# 12 and .NET 8, but most will work with earlier versions as well.

    Conventions used

    There are a number of text conventions used throughout this book.

    Code in text: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: Let’s dive a bit deeper and see what a general implementation of the Result type looks like.

    A block of code is set as follows:

    bool IsBookPopular(Book book)

    {

        if (book.AverageRating > 4.5 && book.NumberOfReviews > 1000)

        {

            return true;

        }

        return false;

    }

    Bold: Indicates a new term, an important word, or words that you see onscreen. For instance, words in menus or dialog boxes appear in bold. Here is an example: Refactor it using Railway-Oriented Programming (ROP) to improve the error-handling flow.

    Tips or important notes

    Appear like this.

    Get in touch

    Feedback from our readers is always welcome.

    General feedback: If you have questions about any aspect of this book, email us at [email protected]

    and mention the book title in the subject of your message.

    Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/support/errata

    and fill in the form.

    Piracy: If you come across any illegal copies of our works in any form on the internet, we would be grateful if

    Enjoying the preview?
    Page 1 of 1