As an OO developer, maybe I have difficulty seeing its value. What added value do they give? Do they fit in an OO world?
Closures don't give you any extra power.
Anything you can achieve with them you can achieve without them.
But they are very usable for making code more clear and readable. And as we all know clean readable short code is a code that is easier to debug and contains fewer bugs.
Let me give you short Java example of possible usage:
button.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent e) {
System.out.println("Pressed");
}
});
Would be replaced (if Java had closures) with:
button.addActionListener( { System.out.println("Pressed"); } );
IMHO it comes down to being able to capture blocks of code and their context to be referenced at some point later on and executed when/if/as required.
They may not seem to be a big deal, and closures definitely aren't something you need to get things done on a daily basis - but they can make code code much simpler and cleaner to write/manage.
[edit - code sample based on the comment above]
Java:
List<Integer> numbers = ...;
List<Integer> positives = new LinkedList<Integer>();
for (Integer number : integers) {
if (number >= 0) {
positives.add(number);
}
}
Scala (skipping some of the other niceties like type inference and wildcards so we're only comparing the effect of the closure):
val numbers:List[Int] = ...
val positives:List[Int] = numbers.filter(i:Int => i >= 0)
Here are some interesting articles:
- Crossing borders: Closures - by Bruce Tate, mentions some advantages of closures
- A Definition of Closures - by Neal Gafter (one of the people who invented one of the closures proposals for Java)
You can see it as a generalization of a class.
Your class holds some state. It has some member variables that its methods can use.
A closure is simply a more convenient way to give a function access to local state.
Rather than having to create a class which knows about the local variable you want the function to use, you can simply define the function on the spot, and it can implicitly access every variable that is currently visible.
When you define a member method in a traditional OOP language, its closure is "all the members visible in this class".
Languages with "proper" closure support simply generalize this, so a function's closure is "all the variables visible here". If "here" is a class, then you have a traditional class method.
If "here" is inside another function, then you have what functional programmers think of as a closure. Your function can now access anything that was visible in the parent function.
So it's just a generalization, removing the silly restriction that "functions can only be defined inside classes", but keeping the idea that "functions can see whatever variables are visible at the point where they're declared".
Closures fit pretty well into an OO world.
As an example, consider C# 3.0: It has closures and many other functional aspects, but is still a very object-oriented language.
In my experience, the functional aspects of C# tend to stay within the implementation of class members, and not so much as part of the public API my objects end up exposing.
As such, the use of closures tend to be implementation details in otherwise object-oriented code.
I use them all the time, as this code snippet from one of our unit tests (against Moq) shows:
var typeName = configuration.GetType().AssemblyQualifiedName;
var activationServiceMock = new Mock<ActivationService>();
activationServiceMock.Setup(s => s.CreateInstance<SerializableConfigurationSection>(typeName)).Returns(configuration).Verifiable();
It would have been pretty hard to specify the input value (typeName) as part of the Mock expectation if it hadn't been for C#'s closure feature.
Maybe in the world of compiled programming the benefits of closures are less noticeable. In JavaScript closures are incredibly powerful. This is for two reasons:
1) JavaScript is an interpreted language, so instruction efficiency and namespace conservation are incredibly important for faster and more responsive execution from large programs or programs that evaluate large amounts of input.
2) JavaScript is a lambda language. This means in JavaScript functions are first class objects that define scope and scope from a parent function is accessible to child objects. This is important since a variable can be declared in a parent function, used in a child function, and retain value even after the child function returns. That means a variable can be reused by a function many times with a value already defined by the last iteration of that function.
As a result closures are incredibly powerful and provide superior efficiency in JavaScript.
The only real benefit of closures is to have smaller scopes and decrease memory consumption and items on the current stack.
Given that "benefit" it appears that closures would better be used as indicators where code needs to be refactored into smaller reusable bits.
For me, the biggest benefit of closures is when you're writing code that starts a task, leaves the task to run, and specifies what should happen when the task is done. Generally the code that runs at the end of the task needs access to the data that's available at the beginning, and closures make this easy.
For example, a common use in JavaScript is to start an HTTP request. Whoever's starting it probably wants to control what happens when the response arrives. So you'll do something like this:
function sendRequest() {
var requestID = "123";
Ext.Ajax.request({
url:'/myUrl'
success: function(response) {
alert("Request " + requestID + " returned");
}
});
}
Because of JavaScript's closures, the "requestID" variable is captured inside of the success function. This shows how you can write the request and response functions in the same place, and share variables between them. Without closures, you'd need to pass in requestID as an argument, or create an object containing requestID and the function.
It's a pity, people no longer learn Smalltalk in edu; there, closures are used for control structures, callbacks, collection enumeration, exception handling and more. For a nice little example, here is a worker queue action handler thread (in Smalltalk):
|actionQueue|
actionQueue := SharedQueue new.
[
[
|a|
a := actionQueue next.
a value.
] loop
] fork.
actionQueue add: [ Stdout show: 1000 factorial ].
and, for those who cannot read Smalltalk, the same in JavaScript syntax:
var actionQueue;
actionQueue = new SharedQueue;
function () {
for (;;) {
var a;
a = actionQueue.next();
a();
};
}.fork();
actionQueue.add( function () { Stdout.show( 1000.factorial()); });
(well, as you see: syntax helps in reading the code)
Edit: notice how actionQueue is referenced from inside the blocks, which works even for the forked thread-block. Thats what makes closures so easy to use.