Proposal for a simplified syntax for invoking @FunctionalInterface methods

Brian Goetz brian.goetz at oracle.com
Thu Mar 23 16:37:24 UTC 2017


[ 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
>>> Then:
>>> *  the statement or expression is compiled as an invocation of the
>>> @FunctionalInterface abstract method on foo's type.
>>>
>>> E.g.
>>>
>>> Function<String, String> doubleString = s -> s + s;
>>>
>>> // prints "hellohello"
>>> System.out.println(*doubleString*("hello"));
>>>
>>> -Timothy
>
>> 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 :-))?
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20170323/8412c5a8/attachment.html>


More information about the compiler-dev mailing list