Allow lambdas to implement abstract classes
brian.goetz at oracle.com
Sun Mar 3 18:54:27 PST 2013
This question is a far deeper one than whether targeting abstract
classes is desirable, or the details of how would it work. It cuts to
the very heart of "what is a lambda".
It is clear that it might be *useful* to be able to convert lambdas to
SAM abstract classes. At some level, that seems an "obvious" thing to
want. But start pulling on that string, and pretty soon you find the
only consistent end to that line of reasoning is that lambdas are
nothing but syntactic sugar for inner classes -- lambdas have to be
objects, they have to have identity, and you are stuck with all the
complex comb-lookup name resolution rules of inner classes. This was
one possible future for Java. It would have been easily and defensible,
but I think it would have been a disappointing outcome. As I outlined
in August 2011
this would have slammed the door on a lot of desirable evolutionary
paths we might want for the future.
Paul is right that functional interfaces are dead simple to grok. But
its not just user simplicity that is important here -- VM simplicity is
too. Making the model simpler opens doors to all sorts of VM
optimizations. (Jettisoning identity is key here.) Functions are
values. Modeling them as objects makes them heavier, and more complex,
than they need to be.
Before throwing this use case under the bus, we did some corpus analysis
to found how often abstract class SAMs are used compared to interface
SAMs. We found that in that corpus, only 3% of the lambda candidate
inner class instances had abstract classes as their target. And most of
them were amenable to simple refactorings where you added a
constructor/factory that accepted a lambda that was interface-targeted.
So in the end it was way less than 3%. Complicating the model for the
sake of a few-percent-use-case seemed a bad trade. The payoff for a
simpler model comes in many forms, including better performance for all
(You may object that we could still "nail abstract class lambda
conversion on the side" by having a different translation scheme for
abstract class lambdas. This is true, but again -- is it worth
complicating the user model -- where some lambdas have identity and some
don't -- for this?)
On 3/3/2013 4:49 PM, Howard Lovatt wrote:
> On 02/03/2013, at 1:23 AM, Paul Sandoz <paul.sandoz at oracle.com> wrote:
>> On Mar 1, 2013, at 2:10 PM, Howard Lovatt <howard.lovatt at gmail.com> wrote:
>>> I remember the previous discussion and just retread it to be sure. The issue raised is with constructors that take arguments or throw checked exceptions.
>> Or constructors that execute code with some side-effects.
>>> You could limit the lambdas to either functional abstract classes that:
>>> 1. Do not have any user supplied constructors
>>> 2. Either 1 above or has a user supplied no-arg constructor that does no throw a checked exception
>> And super classes need to be taken into account.
>> Functional Interfaces are dead simple to grok.
>> Including a restricted form of class that is a functional abstract class adds another dimension for developers, compilers, runtime and tools to understand. Is it worth it?
> Is it worth it? Is the question I am asking. I have found a few examples were it would be useful, even if it was the most restrictive form were the constructor has to be supplied by the compiler. I think it is interesting to explore whether other people have had the same experience and whether these examples are important.
>>From my experimentation the uses of abstract class SAMs is primarily for optimisation since you can always wrap the lambda in a class. I would count optimisation as important particularly for parallel collections, one of the key use cases for lambdas.
> What do others think, is optimisation important?
> -- Howard.
>>> Option 1. Is the most conservative, would the be an objection to 1.
>>> -- Howard.
>>> Sent from my iPad
>>> On 01/03/2013, at 9:19 PM, Paul Sandoz <paul.sandoz at oracle.com> wrote:
>>>> Hi Howard,
>>>> Abstract classes have constructors that will execute user code and thus they can observe and interfere with the process of bootstrapping the lambda expressions. See the following thread for more details:
>>>> On Mar 1, 2013, at 2:54 AM, Howard Lovatt <howard.lovatt at gmail.com> wrote:
>>>>> Would it be useful in other cases if lambdas could implement abstract
>>>>> -- Howard.
More information about the lambda-dev