Mark Needham

Thoughts on Software Development

Functional C#: An imperative to declarative example

with 6 comments

I wrote previously about how we’ve been working on some calculations on my current project and one thing we’ve been trying to do is write this code in a fairly declarative way.

Since we’ve been test driving the code it initially started off being quite imperative and looked a bit like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class TheCalculator
{
	...
	public double CalculateFrom(UserData userData)
	{
		return Calculation1(userData) + Calculation2(userData) + Calculation3(userData);
	}
 
	public double Calculation1(UserData userData)
	{
		// do calculation stuff here
	}
 
	public double Calculation2(UserData userData)
	{
		// do calculation stuff here
	}
	...
}

What we have on line 7 is a series of calculations which we can put in a collection and then sum together:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class TheCalculator
{
	...
	public double CalculateFrom(UserData userData)
	{
		var calculations = new Func<UserData, double>[] { Calculation1, Calculation2, Calculation3 };
 
		return calculations.Sum(calculation => calculation(userData));
	}
 
	public double Calculation1(UserData userData)
	{
		// do calculation stuff here
	}
	...
}

We can pull out a ‘Calculation’ delegate to make that a bit more readable:

public class TheCalculator
{
	private delegate double Calculation(UserData userData);
 
	public double CalculateFrom(UserData userData)
	{
		var calculations = new Calculation[] { Calculation1, Calculation2, Calculation3 };
 
		return calculations.Sum(calculation => calculation(userData));
	}
	...	
}

One of the cool things about structuring the code like this is that if we want to add a new Calculation we can just go to the end of the array, type in the name of the method and then Resharper will create it for us with the proper signature.

We eventually came across some calculations which needed to be subtracted from the other ones, which seems like quite an imperative thing to do!

Luckily Christian saw a way to wrap these calculations in a ‘Subtract’ function so that we could stay in declarative land:

public class TheCalculator
{
	private delegate double Calculation(UserData userData);
 
	public double CalculateFrom(UserData userData)
	{
		var calculations = new [] { Calculation1, Calculation2, Calculation3, Subtract(Calculation4) };
 
		return calculations.Sum(calculation => calculation(userData));
	}
	...	
	public Calculation Subtract(Calculation calculation)
	{
		return userData => calculation(userData) * -1;
	}
}

Having a method which explicitly has the ‘Calculation’ signature allows us to remove it from the array declarative which is pretty neat.

We can also change the method signature of ‘Subtract’ to take in a variable number of calculations if we need to:

public class TheCalculator
{
	...	
	public double CalculateFrom(UserData userData)
	{
		var calculations = new [] { Calculation1, Calculation2, Calculation3, Subtract(Calculation4, Calculation5) };
 
		return calculations.Sum(calculation => calculation(userData));
	}
 
	public Calculation Subtract(params Calculation[] calculations)
	{
		return userData => calculations.Sum(calculation =>  calculation(userData)) * -1;
	}
}

The other nice thing about coding it this way is that we ran into a problem where when we fed real data through the code we were getting the wrong values returned and we wanted to understand where it was falling down.

We could easily temporarily add in a ‘Console.WriteLine’ statement like this to help us out:

public class TheCalculator
{
	...	
	public double CalculateFrom(UserData userData)
	{
		var calculations = new [] { Calculation1, Calculation2, Calculation3, Subtract(Calculation4, Calculation5) };
 
		return calculations
			.Select(calculation =>
					{
						Console.WriteLine(calculation.Method.Name + " = " + calculation(userData));
						return calculation;
					})
			.Sum(calculation => calculation(userData));
	}
	...
}

It then printed the results down the page like so:

Calculation1: 23.34
Calculation2: 45.45
...
Be Sociable, Share!

Written by Mark Needham

April 20th, 2010 at 7:08 am

Posted in .NET

Tagged with ,

  • Usually, a change that makes some code more functional will also make it more declarative, but I do not agree that this is true for today’s example. To me, there isn’t anything imperative at all about “return calc1(data) + calc2(data) + calc3(data)”. Its quite clearly stating what the calculation is, and is not tripped up in the “how”.

    Personally, I found your proposed change to be less clear, especially where you had to use the subtract trick to continue using the sum.

    Just my 2 cents.

  • @Paul I agree with your comment but I think what was gained is that the calculator ‘algorithm’ is now arguably more modular and composeable due to the ‘functional’ additions (with a slight complexity cost). e.g. being able to introduce ‘subtract’ (also personally don’t like the feel of it) and being able to introduce orthogonal responsibilities (logging) more easily.

    @Mark Maybe your example was geared more to show the move to a declarative style but the issue that sticks out for me is that the OCP is violated (although not always a bad thing;)) and eluded to by the mention of re-factoring tool support.
    Generally I’d prefer to reify the calculation (Command + Value Objects) and make the calculator a form of Composite.
    Saying all of this I would consider your example a compromise between the two and therefore a good place to be as you can pretty painlessly move into a more powerful design or out of the current design to a simpler “imperative” style; which is always a good place to be 🙂

  • @carlo yeh there does feel like there’s something wrong with the way that it’s designed at the moment.

    Actually we are newing up individual calculators inside each of those ‘Calculation’ methods and I think you’ve probably pointed out the violation of the OCP as describing exactly what we’ve done wrong. I need to read up a bit more on it to remind myself exactly what it says though!

    I can’t quite picture in my head how the ‘Command + Value Objects’ design for this problem would look? In this case would the commands be the calculators and then you’d be able to compose an object made out of several of them?

  • Open for extension, Closed to modification; I generalise this down to “when adding new behaviour/functionality either extend a type or parameterise a new instance rather than modifying existing implementations”. This should give low coupling/high cohesion.
    So in your example if you have a Composite object (your Calculator) that works off of reified Calculation objects then when adding a new calculation or modifying how a calculation is composed would not affect other calculations or the Composite Calculator. Rather you would create a new calculation and add it (via builder/factory/configuration) to your Calculator composite; so theoretically everything is nice and decoupled at the cost of a more complex model.
    To achieve the ‘declarative’ style the calculation objects would ideally be (DDD style) Value objects, Immutable with side-affect free functions. This would allow easy composition of functions.
    Again this is more complex but probably pay off if new types of calculations are often added; the only changes then are new calculator type and Calculator factory to declare the calculation algorithm i.e. add/subtract etc.

  • Pingback: C#: A failed attempt at F#-ish pattern matching at Mark Needham()

  • Pingback: C#: A failed attempt at F#-ish pattern matching | ASP.NETer()