Wikipedia defines functional programming as: programming paradigm that treats computation as the evaluation
of the mathematical functions and avoids state and mutable data. This is in contrast with the imperative
programming (including object oriented programming) style which emphasizes changes in state. Those who
are interested in finding out what are the benefits of functional programming can read this interesting (at least
to me :-)) blog post by Slava Akhmechet.
Here I will show how can we mimic higher-order function in C# (I said mimic because as you probably know C#
isn't functional language). Functions are higher-order when they can take other functions as arguments and return
them as results. I will demonstrate how we can implement higher-order function filter in C#. To implement filter
function as higher-order function we need to be able to pass functions as arguments. In C# we can only pass
around objects and
primitiv values. So, we have to find a way to have an
object mimic the behavior of a function.
In C# there is a special kind of object, a delegate, that can do the job. C# also has three very helpful features
which we will need. Those are:
- methods can be converted in delegates automatically
- delegates can be defined in-place, where the delegates are needed
- generics can also be applied to delegates
First we will define a delegate (an
object which will mimic the behavior of a function):
public delegate bool Fun<a>(A n);
Then we will define an utility class which will contain our filter function:
class Utilities
{
public delegate bool Fun<a>(A n);
public static List<T> Filter<T>(List<T> list, Fun<T> fun)
{
List<T> filteredList = new List<T>();
foreach (T t in list)
{
if(fun(t))
filteredList.Add(t);
}
return filteredList;
}
}
And that's it. We have implemented higher-order filter function. We can use this function to filter numbers of various
types (integers, floats, doubles). We can use this function to filter numbers which are less then 3, even, greater
then some random number and many more possibilities. All this can be done using the same function which is
defined in one place and which you can easily use in all your projects.
public static void Main(string[] args)
{
List list = new List();
list.AddRange(new int[] { 5, 2, 6, 1, 8, 7, 3, 4, 9 });
//filter numbers less or equal to 3
foreach (int i in
Utilities.Filter(list, delegate(int n) { return n <= 3; }))
{
Console.WriteLine(i);
}
Console.WriteLine();
//filter even numbers
foreach (int i in
Utilities.Filter(list, delegate(int n) { return (n % 2 == 0); }))
{
Console.WriteLine(i);
}
Console.WriteLine();
//filter numbers greater then some random number
Random rnd = new Random();
int j = rnd.Next(9);
foreach (int i in
Utilities.Filter(list, delegate(int n) { return (n > j); }))
{
Console.WriteLine(i);
}
}
<UPDATE>
Note: I'm not suggesting that you should use this Filter function to filter some list. As Miha Markic said in his
comment, for that purpose you should use List<T>.FindAll(Predicate<T> match method. The main purpose of
this blog post was to demonstrate one "functional programming" concept in C# and to make an introduction to
lambda expressions (which will probably be my next post).
</UPDATE>