Re: Proposal for a simplified syntax for invoking @FunctionalInterface methods

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

Re: Proposal for a simplified syntax for invoking @FunctionalInterface methods

Brian Goetz-2
[ moving to compiler-dev ]

This isn't a new suggestion :)  It was discussed initially, and comes around with some regularity as people learn about lambdas in Java. 

As Maurizio suggests, there are technical issues that get in the way (such as the separate namespace for methods and variables).  If we were really motivated to do this, we'd probably accept some complex rules akin to shadowing/obscuring, but there's a deeper, philosophical reason why we think this is a bad fit.  And that is: functional interfaces are not function types, they're class types.  As much as I understand why people wish they were function types, they are not.  Functional interfaces are interfaces, and lambdas are just one way to create an instance of a functional interface -- one can implement a functional interface with named classes, anonymous classes, dynamic proxies, etc. 

A core design principle of the Java language is transparency -- code should do what it looks like it does.  How lambdas are implemented in Java represents a delicate compromise; obscuring this compromise may feel good from a code-writing perspective, but ultimately I think it undermines the transparency of code from a code-reading perspective. 

On 02/03/17 15:10, Timothy Fagan wrote:
I'm not sure if this is the appropriate forum, or if this idea has been
proposed elsewhere, but I'd like to suggest a simplified syntax for
invoking @FunctionalInterface methods.

The idea is that if:
*  foo is a object reference (field, local variable or parameter) whose
type is a @FunctionalInterface
*  there is a statement or expression where foo is used as if it were a
method name
*  the formal parameters of the statement or expression match the formal
parameters of the abstract method on the @FunctionalInterface
*  the formal parameters of the statement or expression do NOT match the
formal parameters of any other method in scope named foo
*  the statement or expression is compiled as an invocation of the
@FunctionalInterface abstract method on foo's type.


Function<String, String> doubleString = s -> s + s;

// prints "hellohello"

Something like this was present in the very first draft of the lambda language support [1] - syntax aside, the main issue with this avenue, is that Java has separate namespaces for methods and fields. That is, you are able to declare a field AND a method whose type is 'doubleString'. So, if you start treating fields in a more method-y way, the namespace issue might pop up, and ambiguities might ensue.
But wouldn’t that just be another layer of name shadowing like we already have on fields? I think it’s all about precedence of field over method or method over field. Do I miss something here (I probably do :-))?