"Closures are poor man's objects and vice versa" - What does this mean?
Objects are poor man's closures.
Consider Java. Java is an object-oriented programming language with no language level support for real lexical closures. As a work-around Java programmers use anonymous inner classes that can close over the variables available in lexical scope (provided they're final
). In this sense, objects are poor man's closures.
Closures are poor man's objects.
Consider Haskell. Haskell is a functional language with no language level support for real objects. However they can be modeled using closures, as described in this excellent paper by Oleg Kiselyov and Ralf Lammel. In this sense, closures are poor man's objects.
If you come from an OO background, you'll probably find thinking in terms of objects more natural, and may therefore think of them as a more fundamental concept than closures. If you come from a FP background, you might find thinking in terms of closures more natural, and may therefore think of them as a more fundamental concept than objects.
Moral of the story is that closures and objects are ideas that are expressible in terms of each other, and none is more fundamental than the other. That's all there is to the statement under consideration.
In philosophy, this is referred to as model dependent realism.
The point is that closures and objects accomplish the same goal: encapsulation of data and/or functionality in a single, logical unit.
For example, you might make a Python class that represents a dog like this:
class Dog(object):
def __init__(self):
self.breed = "Beagle"
self.height = 12
self.weight = 15
self.age = 1
def feed(self, amount):
self.weight += amount / 5.0
def grow(self):
self.weight += 2
self.height += .25
def bark(self):
print "Bark!"
And then I instantiate the class as an object
>>> Shaggy = Dog()
The Shaggy object has data and functionality built in. When I call Shaggy.feed(5)
, he gains a pound. That pound is stored in variable that's stored as an attribute of the object, which more or less means that it's in the objects internal scope.
If I was coding some Javascript, I'd do something similar:
var Shaggy = function() {
var breed = "Beagle";
var height = 12;
var weight = 15;
var age = 1;
return {
feed : function(){
weight += amount / 5.0;
},
grow : function(){
weight += 2;
height += .25;
},
bark : function(){
window.alert("Bark!");
},
stats : function(){
window.alert(breed "," height "," weight "," age);
}
}
}();
Here, instead of creating a scope within an object, I've created a scope within a function and then called that function. The function returns a JavaScript object composed of some functions. Because those functions access data that was allocated in the local scope, the memory isn't reclaimed, allowing you to continue to use them through the interface provided by the closure.
An object, at its simplest, is just a collection of state and functions that operate on that state. A closure is also a collection of state and a function that operates on that state.
Let's say I call a function that takes a callback. In this callback, I need to operate on some state known before the function call. I can create an object that embodies this state ("fields") and contains a member function ("method") that performs as the callback. Or, I could take the quick and easy ("poor man's") route and create a closure.
As an object:
class CallbackState{
object state;
public CallbackState(object state){this.state = state;}
public void Callback(){
// do something with state
}
}
void Foo(){
object state = GenerateState();
CallbackState callback = new CallbackState(state);
PerformOperation(callback.Callback);
}
This is pseudo-C#, but is similar in concept to other OO languages. As you can see, there's a fair amount of boilerplate involved with the callback class to manage the state. This would be much simpler using a closure:
void Foo(){
object state = GenerateState();
PerformOperation(()=>{/*do something with state*/});
}
This is a lambda (again, in C# syntax, but the concept is similar in other languages that support closures) that gives us all the capabilities of the class, without having to write, use, and maintain a separate class.
You'll also hear the corollary: "objects are a poor man's closure". If I can't or won't take advantage of closures, then I am forced to do their work using objects, as in my first example. Although objects provide more functionality, closures are often a better choice where a closure will work, for the reasons already stated.
Hence, a poor man without objects can often get the job done with closures, and a poor man without closures can get the job done using objects. A rich man has both and uses the right one for each job.