can often be a simpler, more concise way to describe the behaviour of a software program than
. I have been an admirer of declarative aspects of programming ever since I started writing SQL queries. We always do our best to write code that is easier to read and maintain. Declarative style is one of the proven ways to write clean code.
is an excellent example of declarative style programming that enables the developers to simply state what they want to do. When I am learning
higher order functions in Haskell
, I have found the interrelationship between the higher order functions and the LINQ. It really made me think in a different way to solve a problem. Through this blog post I would like to share my experiments on
higher order functions
Let me start with a very simple requirement.
Write a program to print the even numbers present in the given n numbers
The code implementation is fairly straight forward below (all code snippets can be enlarged by clicking on them)
Let me add a twist to the code by adding two more requirements.
Modify the program implemented above to print odd numbers and multiples of four present in the given n numbers
To be honest, If I had encountered this requirements before I had learned Higher Order Functions my implementation would be the following.
If you look at the above implementation with a critical eye, you can find a potential candidate of duplication. Let me explain the common pattern that is being used in the implemented PrintXXXX functions.
For each number in the numbers enumerable
Decide whether the number should be printed or not (Deciding)
Print the number if it is passes the above decision (Doing)
All the three functions iterate over the numbers enumerable and print the numbers. The only thing that actually differentiates the functions is deciding which numbers will be printed.
Now the question is how can we eliminate this duplication?
It’s where higher order functions come into picture. If we move the deciding part of the function away from its implementation then we can easily achieve it. Here we go! The brand new implementation of Print would be:
In the new implementation we have just isolated the deciding part of the function from its implementation and parameterized it as a function delegate that takes an integer as its input and returns a Boolean value.
In the client code (Main function) we are actually just calling the print function and declaratively telling it to print only those numbers that satisfy the given condition. As we separated the deciding part from the actual implementation, we can easily accommodate any future requirements like “Printing multiples of five, printing only single digit numbers” by declaratively calling the Print function as you can see below:
Cool.. Isn’t it ? Let me complicate the things little more. What would you do if you want to call this Print method across different classes? A notorious option would be creating a
with the Print method and calling it from the other classes. We can also solve these using
which result in clean readable code like this:
So far, so good. We have started with a single function and then we added two more, then eliminated the duplication using Higher Order functions and finally we have made the code readable by using an extension method.
Okay. Now “I want to print the strings that start with ‘s’ in the given n strings ”. Pardon me for complicating things, I will stop after this one.
It is almost logically similar to what we have done so far. Instead of numbers here, it is a string. How can we put it into action?. By using
. We can easily achieve this by modifying the extension method to support generic types as below
That’s it. Now you are free to play with all sorts of logic you want. You can play with different set of conditions to print the elements or even use different collections of your custom classes. And all can be done declaratively!!
Now its time to reveal to the interrelationship that exists between LINQ and the higher order functions. All the LINQ methods are actually using these Print extension methods under the hood and it makes life easy for the developer while still allowing them to work declaratively.
, a new addition in C# 4.0, also uses higher order functions and enables the developer to say “Hey CLR, I wanna run these methods parallel”.
Awesome! No new thread creation and it's not verbose.
Declarative Programming is a powerful tool. It creates more readable, cleaner code and also saves the possibility of logical mistakes in similar algorithms. That means fewer mistakes now and in the future.