Functional Programming with C#
I’ve been interested in learning more about functional C#, and how it differs from the OOP style C# that I’ve been doing for years. Ed Charbeneau gave a talk on this topic at CodeMash back in January, the main lesson being how to score a poker game using C# and functional principals and the samples. In this blog entry I will be reviewing a few of the functional principals I took away from the presentation— there are many more but here’s a short list:
The first and least obvious functional principal we use is found in LINQ.
Functional Programming is defined as…
“… a style that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data.”
Perhaps what sticks out most to me is the phrase “avoids changing state.” This leads to immutable types which is an object whose state cannot be modified after it is created, lowering the risk of – side-effects.
Next I’ll provide definitions and samples of some of the functional principals that demonstrate immutable types.
You’re already doing some form of functional programming just by using LINQ. LINQ is the gateway to functional programming in C#, and it makes imperative programming routines on arrays and collections much easier. We use this all the time when working with collections. For example, All(), Any(), Skip(), Take(), Where() and Sort() to name a few. They allow for simplified code eliminating imperative foreach loops. This is in itself a functional approach.
Below are two classes that perform the same thing. One is mutable the way I would normally write this in C# and the second is more functional method of expressing this class:
The immutable Rectangle class above cannot change once it is instantiated.
Expressions Instead of Statements
The next major tenet of functional programming is expressions as statements. Both of the expressions below produce the same outcome but the second implementation is immutable.
Function Delegates are the third and perhaps most common principal seen in LINQ. They encapsulate a method usually in the expressed as T1-T6 and TResult. Makes me think of Func<T, Bool>
The below dotnetfiddle code snip demonstrates this:
Higher order Functions / Functions as Data
Simply put this is a function that accepts another function as a parameter or returns another function.
The following excerpt of code demonstrates how to use Count<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>) to count the number of true or false elements in the bools array that satisfy a condition.public int IEnumerable.Count<T>(Func<T, Bool>, predicate). Looks intimidating but, we use it daily in our C# code.
This is I think the most underutilized function in C#. It allows you to define an iterator without the need for an explicit class extra class for the result of the enumeration. We commonly see a new List<X> defined to hold the result of each operation. Yield however eliminates that as seen in the commented out code section. The more functional use is the second implementation as seen below:
In summary, I have covered just a few of the functional programming principals used in C#.
We use LINQ which is inherently functional daily. Functional programming relies on immutable types (not changing state). They make expressions as statements as opposed to longer imperative style code blocks. I reviewed higher order functions/ functions as data and its usage to either pass a function as a parameter or return a function to a calling function. We can’t forget Yield which allows a foreach operation to return the desired element without the need for another class to hold the result of enumeration. These principals tied together could make for a big shift in the way we code.
All code samples illustrated in this article are the work of http://edcharbeneau.com.