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
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.
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.
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:
- 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)
- 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);}}
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