Functional programming for C# developers

Latest Jeremy Miller’s article in MSDN Magazine will be very helpful for C# developers who haven’t started yet exploring functional programming. What is good about this article is that it gives practical advices on how to inject some fairly small pieces of functional programming into existing C# code in order to make it better – for example by removing code duplicates.

What seems to be radical for many C# developers is how functional programming handles blocks of code with variables that are not resolved within those blocks – closures. A piece of code with variables defined somewhere else is traditionally viewed by programmers with background in procedural languages as an invalid construction that will cause a compiler error. But closures are fully supported now in C# (in form of anonymous delegates or lambda-expressions), and Jeremy’s article demonstrates advantages of using this technique to pass around code blocks as data.

I think however that the example with ConnectedSystemConsumer could be presented somewhat simpler, without focus on Interface Segregation Principle. Here’s how the original class looks before refactoring:

class ConnectedSystemConsumer
{
    private readonly IConnectedResource _resource;

    public ConnectedSystemConsumer(IConnectedResource resource)
    {
        _resource = resource;
    }

    public void ManipulateConnectedResource()
    {
        try
        {
            // First, you have to open a connection
            _resource.Open();
            // Now, manipulate the connected system
            _resource.Update(buildUpdateMessage());
        }
        finally
        {
            _resource.Close();
        }
    }

    // The rest of the class is skipped
}

The article then introduces two new interfaces and one class: IResourceInvocation, IResource and Resource, where IResourceInvocation contains the “interesting” part of IConnectedResource (methods FetchData and Update) and IResource defines and Resource implements a single method Invoke that takes care of all ceremony stuff. While this helps splitting the original ConnectedSystemConsumer class into smaller logical blocks, for developer doing his first experiments with functional programming it may leave false impression that adding additional classes are required (or at least expected) steps to take advantage of functional programming in C# code. But the same effect can be achieved without adding new interfaces or classes, just by extracting all ceremony code in a separate method:

class ConnectedSystemConsumer
{
    private readonly IConnectedResource _resource;

    public ConnectedSystemConsumer(IConnectedResource resource)
    {
        _resource = resource;
    }

    public void ManipulateConnectedResource()
    {
        InvokeResource(x =>
        {
            x.Update(buildUpdateMessage());
        });
    }

    private void InvokeResource(Action<IConnectedResource> action)
    {
        try
        {
            // First, you have to open a connection
            _resource.Open();
            // Now, manipulate the connected system
            action(_resource);
        }
        finally
        {
            _resource.Close();
        }
    }

    // The rest of the class is skipped
}

As you can see, ManipulateConnectedResource no longer contains ceremonial code that opens and closes resource and handles exceptions. This code is now moved to InvokeResource method that takes as an argument a block or a closure defined in ManipulateConnectedResource or any other method that requires the same ceremony.

After reading Jeremy Miller’s article I browsed some of my old code and found several classes that can be simplified using the same approach. Perhaps at first they will not look simpler – functional programming style adoption requires some time. But they will become more compact, with less or without code repetition, and this alone is worth it.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s