Mark Needham

Thoughts on Software Development

Archive for the ‘functional-collection-parameters’ tag

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.

Written by Mark Needham

June 18th, 2009 at 6:31 pm

Functional Collection Parameters: Handling the null collection

with 5 comments

One of the interesting cases where I’ve noticed we tend to avoid functional collection parameters in our code base is when there’s the possibility of the collection being null.

The code is on the boundary of our application’s interaction with another service so it is actually a valid scenario that we could receive a null collection.

When using extension methods, although we wouldn’t get a null pointer exception by calling one on a null collection, we would get a ‘source is null’ exception when the expression is evaluated so we need to protect ourself against this.

As a result of defending against this scenario we have quite a lot of code that looks like this:

public IEnumerable<Foo> MapFooMessages(IEnumerable<FooMessage> fooMessages)
{
	var result = new List<Foo>();
	if(fooMessagaes != null)
	{
		foreach(var fooMessage in fooMessages)
		{
			result.Add(new Foo(fooMessage));
		}
	}
	return result;
}

The method that we want to apply here is ‘Select’ and even though we can’t just apply that directly to the collection we can still make use of it.

private IEnumerable<Foo> MapFooMessages(IEnumerable<FooMessage> fooMessages)
{
	if(fooMessages == null) return new List<Foo>();
	return fooMessages.Select(eachFooMessage => new Foo(eachFooMessage));
}

There’s still duplication doing it this way though so I pulled it up into a ‘SafeSelect’ extension method:

public static class ICollectionExtensions
{
       public static IEnumerable<TResult> SafeSelect<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
       {
               return source == null ? new List<TResult>() : source.Select(selector) ;
       }
}

We can then make use of this extension method like so:

private IEnumerable<Foo> MapFooMessages(IEnumerable<FooMessage> fooMessages)
{
	return fooMessages.SafeSelect(eachFooMessage => new Foo(fooMessage));
}

The extension method is a bit different to the original way that we did this as I’m not explicitly converting the result into a list at the end which means that it will only be evaluated when the data is actually needed.

In this particular case I don’t think that decision will have a big impact but it’s something interesting to keep in mind.

Written by Mark Needham

June 16th, 2009 at 8:29 pm