Mark Needham

Thoughts on Software Development

Functional Collection Parameters: A different way of thinking about collections

without comments

One of the changes that I’ve noticed in my coding now compared to around 7 or 8 months ago is that whenever there’s some operations to be performed on a collection I am far more inclined to think of how to do those operations using a functional approach.

I’ve written previously about the ways I’ve been making use of functional collection parameters in my code but what I hadn’t really considered was that the way of thinking about the problem we want to solve is slightly different.

While Dean and I were talking through the refactoring that I mentioned in my post about handling null collections, we realised that the way it was originally written followed a very sequential mindset.

public IEnumerable<Foo> MapFooMessages(IEnumerable<FooMessage> fooMessages)
{
	var result = new List<Foo>();
	if(fooMessages != null)
	{
		foreach(var fooMessage in fooMessages)
		{
			result.Add(new Foo(fooMessage));
		}
	}
	return result;
}
  • Create a new collection
  • Take an existing collection
  • If it’s not null then iterate over the existing collection
  • Add each item to the new collection
  • Return the new collection

I find when I’m thinking about doing this type of code now my thought process is more focused towards the collection as a whole rather than about the individual items in the collection.

If I do want to only apply an operation on a subset of the collection then I need to first apply another function to the whole collection that filters the collection down. I find myself thinking about what I want to happen rather than how I want to do it – a declarative approach over an imperative one in summary.

One of the LINQ C# extension methods which I sometimes find myself abusing is the ‘ForEach’ one which I feel is used a lot more times than is necessary and often ends up with complicated lambda blocks inside it which could be avoided by using some of the other functions.

To give a very simple example of some code I came across recently:

public IEnumerable<string> GetFooKeys(IEnumerable<Foo> foos)
{
	var list = new List<string>();
	foos.Where(foo => foo.Opted).ToList().ForEach(foo => list.Add(foo.Key));
	return list;
}

We are making use of functional collection parameters but we can easily do this without using the ‘ForEach’ method:

public IEnumerable<string> GetFooKeys(IEnumerable<Foo> foos)
{
	return foos.Where(foo => foo.Opted).Select(foo => foo.Key);
}

I think the danger with ‘ForEach’ is that we are creating side effects which may be unexpected. In this case there’s not really that much problem as we’re just adding a value to a list but it is possible to do anything else in the ForEach block as well.

I also came across a good post written by one of the 8th light guys talking about the use of ForEach in Scala and how we can use it in a way that minimises side effects.

Be Sociable, Share!

Written by Mark Needham

June 18th, 2009 at 6:31 pm