Functional programming has become popular recently, and many object oriented languages (C#, Scala, Java) have begun including functional concepts as part of the language. Here we’ll go over a few functional ideas in C#. If you’re a C programmer, it might be useful to think about all of this stuff in terms of function pointers. In practice, `Func`s and function pointers pretty much do the same thing. If you look at the declaration for C’s standard `qsort`:
void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
The `(*compar)` function pointer is a block of code you’re passing into the `qsort` function. It gets executed whenever the `qsort` implementation decides it wants to compare values. Pretty often I’ve found myself needing to wait for things to happen. This is especially true when I’m baking. If I were to automate my baking I’d need a way to wait for the different operations to complete. With procedural code I’d probably write some things like this:
Ok, that’s not too bad, but there’s a bunch of copy and pasted code. I hate that!
One of the core principles of functional programming is code as data. This means we can assign blocks of code to variable names and pass blocks of code as method parameters. Let’s see what something that takes a block of code as a method parameter looks like:
Here, we’re passing in a `Func<bool>` object named `predicate`. `Func<bool>` is a type name that signifies a block of code that returns a `bool`. Calling `predicate()` in the method body executes the code that was passed in via the method parameter. So, how would you actually use that?
Here’s a simple example that doesn’t really do anything useful:
var done = Wait(() => false;
All this will do is block the current thread forever. That’s because the predicate will always return false, so we’ll just keep delaying for 1 minute. Not very useful.
The syntax is a bit odd here if you’re not used to it. The `()` means that we’re not passing anything into the `Func<>`. If you use something like `Func<int, bool>` you’d be able to pass in an integer which we’ll see later on. The `=>` means we’re starting a block of code to pass in. Everything after the `=>` is the block of code that will be run when the `Wait` method calls `predicate()`. If you run this in a debugger and step into the call to `predicate()` you’ll see that execution jumps to that `return false` code. To make things more readable you can wrap the block of code you’re passing in in curly braces. To update our original example for waiting for the dough to rise we’d have something like this:
That’s a little bit better since we don’t have to copy the Thread.Sleep call everywhere, but there’s still too much copy and paste code for me.
The code from the last section still isn’t as general as it could be. We’d still need to implement the same logic for checking if a counter is less than a timeout value and incrementing it if it isn’t. Let’s see if we can do better.
By passing more data into the anonymous function we can shorten things a bit further:
That’s a little nicer, and it uses a bit less of copied code. The `WaitFor…` methods are about half the lines as the previous iteration. This is mostly an example to show how to pass data into an anonymous function. You can see that where we’re passing `(currentTime)` into the `Wait` methods, `Func<int, bool>`. Note here that the order of the type parameters to a `Func` indicate which direction they’re going in. The last type parameter is always the return value. So, `Func<int, bool>` is an anonymous function that take an integer parameter and
returns a `bool`.
That’s about all you need to know. If you’re a C programmer and understand function pointers, this should all make sense conceptually. Once you figure out the syntax it’ll all become more clear.
If you want to learn more, the first thing to research is LINQ . LINQ was introduced in .NET 3.5 and provides a lot of really useful ways to deal with collections of data. It uses functional programming techniques heavily to reduce the lines of code you need to write.
More from my site