views:

539

answers:

5

I don't understand how closure is more powerful than class. It looks like I can achieve the same behavior of closure using class. Any help would be appreciated

+3  A: 

A closure and a class are two very different things.

It is not correct to say 'A class is more powerful that a closure.' or vise a versa.

They do totally different things.

A closure is in a basic sense, a function call that retains the local variable information from the scope it was created.

A class is a definition of an object. The class defines behavior and the contents of instances of the class.

jjnguy
Doesn't a closure retain the variables from the scope in which it's declared? (not called, necessarily)
recursive
oops. thanks .
jjnguy
and it should be mentioned that javascript has a prototype system
Mike Axiak
+2  A: 

I'm not sure what led you to this question, but something you've been told or something you read has severely misled you.

Ignoring language altogether, a closure and a class are completely unrelated structures/conventions in programming.

Peter Bailey
syntactically may be, but you can emulate one with the other in java for example, and they are not tooo different from each other when you start thinking about it.
Chii
+9  A: 
Shog9
thank you for the koan.
Waylon Flinn
Will I become enlightened when I figure out how to pronounce Qc Na?
Michael Myers
It sounds like one hand clapping.
Sebastián Grignoli
+4  A: 

The differences between a class and a closure have been explained by others already. I just wanted to point out that in many places in the Java API where a language that supported them would/could use closures, an anonymous implementation of an interface is used. For instance consider the code below:

JButton btn = new JButton("Say Hello");
btn.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        JOptionPane.showMessageBox("Hello");
    }
});

In this case the anonymous ActionListener could be said to be acting as a closure, if Java allowed closures, the code might look like this: (using c++0x-esque syntax)

JButton btn = new JButton("Say Hello");
btn.addActionListener([]=>(ActionEvent e){JOption.showMessageBox("Hello");});

In this trivial case, the main difference between a closure and an anonymous implementation of an interface (AII) is that:

  1. The AII method has stronger type checking than a closure. (Closure systems can be made to have stronger type checking, but in general, they aren't)
  2. The closure syntax requires less typing. This seems to be the main gripe that renders out once you chew on the Java need closures arguments long enough.

I have yet to run into a situation where AII can't do what needs doing. Yes, there is more typing and another interface to define, but they system works and is, IMHO, more powerful since you needn't use an AII but rather can use a full-fledged class with it's own methods, member data, and constructor. An example is an action listener that pops up a context menu. If you make a class that implements ActionListener and takes a JMenu as it's argument, you can do:

btn.addActionListener( new ContextMenuActionListener(myMenu) );

This looks cleaner (to me) than a boost:bind type solution.

[]=>(ActionListener) myContextPopupClosure = []=>(ActionListener E){ ... };
...
btn.addActionListener( Closure.bind1(myContextPopupClosure,myMenu) );

or so

EDIT:

After doing a lot of work last night messing with generics, I realized one advantage of closures over AII. In the above examples, I have been assuming that the closure would be of type []=>(ActionEvent), but it really could be of the type []=>(? super ActionEvent). This means:

[]=>(Object) c = []=>(Object o) { System.exit(0); }
btn.addActionClosure( c );
window.addMouseMovedClosure( c );
//Each method in MouseMotion listener would need it's own closure.
//So I 'invented' an API change.

Would be compilable. This could prove useful, for when you need to do the same thing in response to multiple events.

Another example. This closure could be added to any place that takes a closure. If added to something as an ActionListener or MouseListener, it would log calls.

[]=>(Object ... objs) log = []=>(Object ... obj) {for(Object o:obj){logObject(o);}}
KitsuneYMG
+1  A: 

This is a good question but could be better worded:

"What are some similarities and differences between Java objects and JavaScript closures"?

Similarities: they both have persistent state in their local variables. Their methods have access to those state variables.

Differences: Javascript is a functional language, therefore functions within functions can be immediately invoked and returned. For example:

newXY = function(x,y) {

    var that = {};//Instantiate new object
    var x = parseFloat(x);
    var y = parseFloat(y);

    that.xtimesy = function() {
      return x*y;
    }(); // <-- Notice the immediate invocation of the function, here.

    return that;
};

So you can write code like this snippet copy / pasted from rhino shell:

js> var foo = newXY(2,5);
js> foo.xtimesy;
10
Julien Chastang