Lambda expression as a succinct way to pass in type parameter
Rémi Forax
forax at univ-mlv.fr
Tue Nov 15 01:11:47 PST 2011
On 11/15/2011 03:19 AM, Zhong Yu wrote:
> On Mon, Nov 14, 2011 at 5:48 PM, Dan Smith<daniel.smith at oracle.com> wrote:
>> On Nov 14, 2011, at 11:57 AM, Zhong Yu wrote:
>>
>>> Suppose a method parameter type is a SAM interface, we must then
>>> document whether a lambda expression argument is acceptable. That
>>> depends on how the method uses the argument. If the method does
>>> nothing but invoking the single abstract method, obviously lambda
>>> expression is acceptable. But beyond that, what kinds of usages of the
>>> argument makes lambda expression unacceptable? Where's the line that
>>> differentiate lambda expressions from "classical" objects?
>> There's nothing magic about the lambda class's implementation -- it's a perfectly normal class, requiring no special treatment from the VM. It's just that the class that you get isn't quite what you're expecting.
>>
>> What you want:
>>
>> class LambdaImpl implements TypeToken<Bar> { ... }
>>
>> What you get:
>>
>> class LambdaImpl<T> implements TypeToken<T> { ... }
>>
>> or maybe
>>
>> class LambdaImpl implements TypeToken /*raw*/ { ... }
>>
>> To give a sense of exactly what implementations are required to do (and what aspects of the class are unspecified), I expect the language specification to ultimately include a section saying something like "the class of which the lambda expression's value is an instance has the following properties: ..."
> Well, who has the time to read the spec...
>
> Is the overhead of a new class really so high that such optimization
> is justified?
A new class has several overheads, it increases jar size, loading time,
verification time, etc
but here the idea is more if there is only one generated class for all
lambdas using
the same SAM type then the JIT will be able to see through it and at the end
be able to inline the lambda with the code of the method that takes a lambda
as parameter.
So it's important because nobody want slow lambda.
>
>> FWIW, if you don't mind being explicit about the type, but you're not satisfied with what you get from ".class" (no generics, etc.), you could always use an anonymous inner class:
>>
>> foo(new TypeToken<List<String>>(){});
> Of course it's just too repetitive:
>
> List<String> ls = foo(new TypeToken<List<String>(){});
>
> It gets worse if we want to avoid creating a new object for each call,
>
> List<String> ls = foo(TYPE);
> static final TypeToken<List<String>> TYPE = new TypeToken<List<String>(){};
>
> This is really unfortunate. I've witnessed many questions on
> stackoverflow.com that can be traced to the lack of type literal in
> Java. It has significant amount of use cases.
>
> (Actually if all types are reified, many of the problems can be solved
> without needing type literal; in our example, it would be nice to
> simply write `List<String> ls=foo();` But that's out of discussion
> because I assume there is zero chance to ever take erasure out of
> Java.)
>
> </whine>
No, it's possible to have reified generics types in Java but not in Java 8.
> Zhong Yu
Rémi
More information about the lambda-dev
mailing list