Library tutorials & articles

The Beauty of Closures

Introduction

Most articles about closures are written in terms of functional languages, as they tend to support them best. However, that's also precisely why it's useful to have an article written about how they appear more traditional OO languages. Chances are if you're writing in a functional language, you know about them already. This article will talk about C# (versions 1, 2 and 3) and Java (before version 7).

What are closures?

To put it very simply, closures allow you to encapsulate some behaviour, pass it around like any other object, and still have access to the context in which they were first declared. This allows you to separate out control structures, logical operators etc from the details of how they're going to be used. The ability to access the original context is what separates closures from normal objects, although closure implementations typically achieve this using normal objects and compiler trickery.

It's easiest to look at a lot of the benefits (and implementations) of closures with an example. I'll use a single example for most of the rest of this article. I'll show the code in Java and C# (of different versions) to illustrate different approaches. All the code is also available for download so you can tinker with it.

Example situation: filtering a list

It's reasonably common to want to filter a list by some criterion. This is quite easy to do "inline" by just creating a new list, iterating over the original list and adding the appropriate elements to the new list. It only takes a few lines of code, but it's still nice to hide that logic away in one place. The difficult bit is encapsulating which items to include. This is where closures come in.

Although I've used the word "filter" in the description, it's somewhat ambiguous between filtering items in the new list and filtering things out. Does an "even number filter" keep or reject even numbers, for instance? We'll use a different bit of terminology - a predicate. A predicate is simply something which matches or doesn't match a given item. Our example will produce a new list containing every element of the original list which matches the given predicate.

In C# the natural way of representing a predicate is as a delegate, and indeed .NET 2.0 contains a Predicate type. (Aside: for some reason LINQ prefers Func; I'm not sure why, given that it's less descriptive. The two are functionally equivalent.) In Java there's no such thing as a delegate, so we'll use an interface with a single method. Of course we could use an interface in C# as well, but it would be significantly messier and wouldn't let us use anonymous methods and lambda expressions - which are precisely the features which implement closures in C#. Here are the interface/delegate for reference:

// Declaration for System.Predicate<T>
public delegate bool Predicate<T>(T obj)
// Predicate.java
public interface Predicate<T>
{
    boolean match(T item);
}

The code used to filter the list is very straightforward in both languages. I should point out at this stage that I'm going to steer clear of extension methods in C# just to make the example simpler - but anyone who has used LINQ should be reminded of the Where extension method. (There are differences in terms of deferred execution, but I'll avoid those for the moment.)

// In ListUtil.cs
static class ListUtil
{
    public static IList<T> Filter<T>(IList<T> source, Predicate<T> predicate)
    {
        List<T> ret = new List<T>();
        foreach (T item in source)
        {
            if (predicate(item))
            {
                ret.Add(item);
            }
        }
        return ret;
    }
}

// In ListUtil.java
public class ListUtil
{
    public static <T> List<T> filter(List<T> source, Predicate<T> predicate)
    {
        ArrayList<T> ret = new ArrayList<T>();
        for (T item : source)
        {
            if (predicate.match(item))
            {
                ret.add(item);
            }
        }
        return ret;
    }
}

(In both languages I've included a Dump method in the same class which just writes out the given list to the console.)

Now that we've defined our filtering method, we need to call it. In order to demonstrate the importance of closures, we'll start with a simple case which can be solved without them, and then move on to something harder.

Comments

  1. 13 Nov 2008 at 03:43
    Dear Jon, Thanks for taking the time to writing this great introduction to closures in C# and Java. By the way, have you had the chance to look at the [Umbrella project](http://www.codeplex.com/umbrella) (via CodePlex)? It's a .NET library that offers many helper/utility methods to easily work around various objects, pretty much using the same approach as your article. Though the code isn't highly documented, it's written explicitly enough to understand it. It's one of those libraries that should belong in everyone's lib folder ;) Brian www.BrianOnSoftware.com
  2. 26 Aug 2009 at 22:44

    Thanks Jon for a clear well-written article. I reached this article after downloading Ruby, and wanted to brush up on closures and some other supported language features. I appreciate the full code examples- many times authors leave out details, which can make the reader feel as if he or she is "missing something". Best Regards, Mark

  3. 12 Feb 2010 at 23:40

    Hi !

    I think, it's even more complicate in C#. Im using this usual trick [declare local variable and assign it's the loops var] while I am creating Tasks ..... The called method got other values on each run ... ! Really strange! I feel, it would be better tow write two more clean understandable lines of code - like in your java-sample - then ever deal with lamba's [too abstract for me and I am getting completely unexpected results, each time, I try to use them] !!

    br--mabra

Leave a comment

Sign in or Join us (it's free).

Jon Skeet C# MVP currently living in Reading and working for Google.

Related discussion

Related podcasts

  • python411: Language Comparisons

    Published 1 year ago, running time 0h31m

    Comparing Python to Ruby, Perl, Java, C#, VB.Net, C, C++, JavaScript, PHP etc. c, language, python, ruby

Related jobs

Events coming up

  • Sep 4

    iPhone Coding Dojo, Building Apps 4 iPhone using MonoTouch

    Cambridge, United Kingdom

    Relaxing end to another hard week with good Beer, laptops, friends, and coffee , 6:30 till whenever ... Every Friday at CB2 Bistro. (check the website each week to confirm the venue, will be exploring some other venues soon.)The challenge for tonight as a coding Dojo is to build an App for a Jailbroken IPhone using Monotouch.

Want to stay in touch with what's going on? Follow us on twitter or Facebook!