 |
Closure Litteral and Method Reference
Posted by forax on February 27, 2007 at 03:46 AM | Comments (11)
Recently, Stephen Colebourne and Stefan Schulz post another closure like proposal, yes, yet another one.
They propose another syntax for describing a closure
which, in my opinion, is more a simpler way
to declare an inner-class.
I am not a big fan of this proposal,
i definitively prefer the
closure syntax
decribed by Neal Gafter.
But there is something that i like in their proposal,
the fact that you can create invocable method references.
Invocable Method Reference
We need a way to easily create a reference to a method,
an object that allow to call a method.
Currently a method is not an Object
and if you want something like that
you have to use reflection (java.lang.reflect.Method)
which is not type-safe, uses lot of checked exceptions
and performs primitive boxing and array boxing.
So having a way to create a method reference is a good think.
But unlike Stephen and Stefan, i don't think that
a method reference is a java.lang.reflect.Method correctly typed
by the compiler but instead a java.function object (a closure)
of Neal.
In my opinion method reference is a kind of closure litteral,
so this code snippet:
public void init() {
JButton button = ...;
button.addActionListener(this#handleAction(ActionEvent));
}
public void handleAction(ActionEvent ev) {
// handle event
}
is a short syntax for:
public void init() {
JButton button = ...;
button.addActionListener({ActionEvent e=>
handleAction(e);
});
}
public void handleAction(ActionEvent ev) {
// handle event
}
Because a method reference is a closure litteral,
the type of a method reference is a function type.
{ActionEvent=>void} handle = this#handleAction(ActionEvent);
I think that using # is a good idea.
Perhaps because it's the syntax i choose to use
to create property litteral (property reference)
in my next property proposal that
i will post in few days.
Cheers, Rémi
Bookmark blog post: del.icio.us Digg DZone Furl Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment
-
"But unlike Stephen and Stefan, i don't think that a method reference is a java.lang.reflect.Method correctly typed by the compiler but instead a java.function object (a closure) of Neal."
If you read a little closer, the FCM proposal introduces method references that are typed like Neal's functions, but that the method references can be assigned to Method. This is nice for using existing APIs that rely on Method.
Posted by: ricky_clarkson on February 27, 2007 at 05:52 AM
-
Funny and sad to see Java heading the way of other "${fugly}" languages with all those '=>' and '#' (and whats next, who can beat the redundancy by introducing a THREE letter symbol.
Apparently implementing a context sensitive parser, is not reasonable. So they introduce all those symbols, muddying up one of the last easy on the eye languages.
Closures is a nice proposal. Someone in position to gauge Java's future should seriously reconsider the aesthetics of
{ int x, int y => x + y }
or something that includes the '#' symbol, which looks no less out of place.
see: http://www.artima.com/forums/flat.jsp?forum=226&thread=189212&start=15
Posted by: jnice on February 27, 2007 at 06:40 AM
-
# already exists in Java, in javadoc.
While some of Ste{phe,fa}n's proposal could be done with '.' instead of #, not all can be. E.g., object#toString() is a reference to that method. object.toString() already means something.
jnice, if you want to show that you're not just a troll, come up with an alternative syntax that makes sense.
Posted by: ricky_clarkson on February 27, 2007 at 07:12 AM
-
Hi Remi,
Unfortunately, we haven't communicated the detail of the proposal well enough to you. The invocable method reference is to be implemented as an inner class in exactly the way you indicate. See section VI.
Secondly, there really isn't a whole lot of difference between an inner method and a BGGA closure implementing RestrictedFunction. The key difference is that FCM uses return, whereas BGGA uses last-line-no-semicolon. So, is it the syntax or the semantics that you dislike?
Stephen Colebourne
Posted by: scolebourne on February 27, 2007 at 07:14 AM
-
ricky_clarkson:
Nice troll defense, always works.
see: http://jroller.com/page/scolebourne?entry=first_class_methods_java_style
Posted by: jnice on February 27, 2007 at 07:44 AM
-
Ricky, the proposal clearly says the opposite in section II
"Method literals are, by definition, instances of Method",
and in section VI,
method litteral can be converted to method type.
Stephen, i dislike the fact that you use Method
behind the scene.
About the syntax, i agree with you that using the last-line to return
a value is ugly but we really need real closure, i.e a way to separate
the traversal of a data structure from the computational aspect.
Perhaps restricted functions and closures deserve
different syntax, i don't know.
Rémi
Posted by: forax on February 27, 2007 at 01:38 PM
-
Remi,
The proposal has three syntax elements. Method literals are Method objects are you point out. But there are two other syntax elements which aren't based on Method objects - invocable method references and inner methods. It is a misunderstanding of the spec to say that we always use a Method object behind the scenes. (A Method object is only created for method literals, not for method references or inner methods. Method literals are not intended to be used as closures.).
Not sure what you're driving at with the traversal vs computational comment.
Stephen Colebourne
Posted by: scolebourne on February 27, 2007 at 05:04 PM
-
I do really like this proposal as it basically kills two birds with one stone-- use dot notation for evaluation, # for referencing. This is especially pertinent if you could reference property *instances* via # syntax while still using dot notation for property evaluation. For change listeners and framework integration, it would be ideal. I'd almost do away with anonymous closures with the understanding that methods/variable scoping doesn't change from what it's always been in Java (you can have a closure, but it's owned/declared by some class).
Posted by: jhook on February 28, 2007 at 10:38 AM
-
What many people don't seem to realize is that Stephan and Stefan are not trying to solve the entire closure problem. They're trying to solve one aspect of the problem in a way that is very amenable to Java and still feels like java syntax. They're proposal "First Class Methods" not closures. Were their proposal already in place, supporting closures would be an almost trivial addition.
At any case, if we're going to introduce new syntax, why not just introduce the "yield" keyword and be done with it? If backward compatibility is a concern, then let "yield" be considered a keyword only within the scope of an anonymous inner method.
I would imagine that the "public" modifier on local variables as suggested in CICE would suffice to bridge the rest of the gap.
Posted by: qualidafial on February 28, 2007 at 03:58 PM
-
Remi, I think you missed some a key point of the proposal. A method literal such as Object#toString() can be a java.lang.reflect.Method or it can be converted inline to a statically typed meta-method pointer (similar to java.function objects):
Object obj = ...
#(String()) method = obj#toString();
method.invoke();
What is happening here is the compiler generates an adapter class on the fly, and this class has a single method "invoke" with the same signature as the method referred to in the literal. When the "invoke" method is called, it just forwards the call to the actual object, with the same parameters:
Object obj = ...
class #(String()) {
Object target;
public #(String()) (Object target) {
this.target = target;
}
public String invoke() {
return target.toString();
}
}
#(String()) method = new #(String()) (obj);
method.invoke();
Using this form of the FCM syntax does not involve any reflection at all (and therefore no additional overhead).
The usage below does use reflection though, because we are referring to an instance method in a static way:
Object#toString().invoke(obj);
Note the difference between obj#toString() and Object#toString()
Posted by: qualidafial on February 28, 2007 at 04:25 PM
-
The C3S proposal suggests method instead of #, the example in C3S is:
declare button = ...;
button.addActionListener method ( e ) { handleAction e };
Posted by: hlovatt on March 07, 2007 at 10:23 PM
|