views:

155

answers:

3

What are the pros and cons of closures against classes, and viceversa?

Edit: As user Faisal put it, both closures and classes can be used to "describe an entity that maintains and manipulates state", so closures provide a way to program in an object oriented way using functional languages. Like most programmers, I'm more familiar with classes.

The intention of this question is not to open another flame war about wich programming paradigm is better, or if closures and classes are fully equivalent, or poor man's one-another.

What I'd like to know is if anyone found a scenario in wich one approach really beats the other, and why.

+1  A: 

Closures are very lightly related to classes. Classes let you define fields and methods, and closures hold information about local variables from a function call. There is no possible comparison of the two in a language-agnostic manner: they don't serve the same purpose at all. Besides, closures are much more related to functional programming than to object-oriented programming.

For instance, look at the following C# code:

static void Main(String[] args)
{
    int i = 4;
    var myDelegate = delegate()
    {
        i = 5;
    }

    Console.WriteLine(i);
    myDelegate();
    Console.WriteLine(i);
}

This gives "4" then "5". myDelegate, being a delegate, is a closure and knows about all the variables currently used by the function. Therefore, when I call it, it is allowed to change the value of i inside the "parent" function. This would not be permitted for a normal function.

Classes, if you know what they are, are completely different.

A possible reason of your confusion is that when a language has no language support for closures, it's possible to simulate them using classes that will hold every variable we need to keep around. For instance, we could rewrite the above code like this:

class MainClosure()
{
    public int i;

    void Apply()
    {
        i = 5;
    }
}

static void Main(String[] args)
{
    MainClosure closure;
    closure.i = 4;

    Console.WriteLine(closure.i);
    closure.Apply();
    Console.WriteLine(closure.i);
}

We've transformed the delegate to a class that we've called MainClosure. Instead of creating the variable i inside the Main function, we've created a MainClosure object, that has an i field. This is the one we'll use. Also, we've built the code the function executes inside an instance method, instead of inside the method.

As you can see, even though this was an easy example (only one variable), it is considerably more work. In a context where you want closures, using objects is a poor solution. However, classes are not only useful for creating closures, and their usual purpose is usually far different.

zneak
I thought the same, but there's apparently quite a bit of debate over whether closures or objects are more expressive. Let me give you a bit of a taste of the discussion: http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html
Faisal
According to my understanding, you can implement objects via closures, and you can simulate closures up to a point via objects. However, objects do not normally automatically capture the local environment, so you would have to explicitly initialize them... But @zneak is correct: they ultimately serve two different purposes, and wanting both is not unreasonable.
Amadan
@Faisal: I believe this debate is about explicitly using closures vs. creating a class to simulate a closure, in which case "full-fledged" closures are obviously more convenient.
zneak
@Amadan, @zneak, what is the fundamental property of closures that makes them a superset of objects?
Michael Foukarakis
@zneak: why would you use a class to simulate a closure if closures were available to you as a language construct? i agree that the conclusion you draw is obvious, though. :)
Faisal
@mfukar that would be that closures, by definition, capture their environments. Instances do not necessarily do so.
jeremiahd
@Faisal: You don't want to use a class to simulate a closure if you don't have to. That's stupid. I made the example because C# supports both, and it's easier to show the comparison (what when you have closures, and what if you don't).
zneak
@mfukar: Closures are a superset of objects because they can be represented as instances of a class with a field for each captured variable, and a single "apply" method. The rest is syntax sugar (though very useful syntax sugar).
zneak
@zneak: judging by his comments on other related questions, I assume he wants to know whether it's better to describe an entity that maintains and manipulates state (to avoid using loaded words like "instance" or "object") via closures or classes. there are languages (lisp, for instance), in which closures are used to construct what OOPers would call classes (or, more appropriately, instances of classes). on the other hand, classes can be used as closures, as you demonstrated. (actually, from your response to mfukar i imagine you already appreciate this idea, so take the above as you will...)
Faisal
Faisal is right about the intention of my question.
Sebastián Grignoli
+7  A: 

Functionally, closures and objects are equivalent. A closure can emulate an object and vice versa. So which one you use is a matter of syntactic convenience, or which one your programming language can best handle.

In C++ closures are not syntactically available, so you are forced to go with "functors", which are objects that override operator() and may be called in a way that looks like a function call.

In Java you don't even have functors, so you get things like the Visitor pattern, which would just be a higher order function in a language that supports closures.

In standard Scheme you don't have objects, so sometimes you end up implementing them by writing a closure with a dispatch function, executing different sub-closures depending on the incoming parameters.

In a language like Python, the syntax of which has both functors and closures, it's basically a matter of taste and which you feel is the better way to express what you are doing.

Personally, I would say that in any language that has syntax for both, closures are a much more clear and clean way to express objects with a single method. And vice versa, if your closure starts handling dispatch to sub-closures based on the incoming parameters, you should probably be using an object instead.

clacke
+3  A: 

Personally, I think it's a matter of using the right tool for the job...more specifically, of properly communicating your intent.

If you want to explicitly show that all your objects share a common definition and want strong type-checking of such, you probably want to use a class. The disadvantage of not being able to alter the structure of your class at runtime is actually a strength in this case, since you know exactly what you're dealing with.

If instead you want to create a heterogeneous collection of "objects" (i.e. state represented as variables closed under some function w/inner functions to manipulate that data), you might be better off creating a closure. In this case, there's no real guarantee about the structure of the object you end up with, but you get all the flexibility of defining it exactly as you like at runtime.

Thank you for asking, actually; I'd responded with a sort of knee-jerk "classes and closures are totally different!" attitude at first, but with some research I realize the problem isn't nearly as cut-and-dry as I'd thought.

Faisal
In other words, closures-as-objects are more like *interfaces* in most OOP languages--the internal representation is completely hidden, and anything providing the same public methods can be swapped in. Some people actually think this is better OOP style, amusingly...
camccann