lambda or reified lambda
forax at univ-mlv.fr
Thu Nov 19 06:20:53 PST 2009
Neal Gafter a écrit :
> On Wed, Nov 18, 2009 at 1:37 PM, Rémi Forax <forax at univ-mlv.fr
> <mailto:forax at univ-mlv.fr>> wrote:
> Hi Neal,
> I've just read your new proposal for lambda in Java (v0.6a).
> A small remarks, I think that defined @Shared as an annotation
> is not necessary. 'shared' as a local keyword should be better.
> Since it only suppresses a warning, even a context-sensitive keyword
> seems overkill.
> Your proposal doesn't say that function types are not reified:
> The proposal defines function types as instances of generic
> interfaces. If interfaces are not reified, then it follows logically
> that function types are not reified and therefore need not be specified.
> #int(String) fun = #(String text) text.length();
> #int(Object) fun2 = fun; // ok, subtyping
> #int(String) fun3 = (#int(String))fun2; // unsafe warning.
> What is the reason to not use method handle to implement lambdas ?
> You will get reification for free.
> On the contrary, there are many issues preventing that. Here are two
> First, method handles do not have VM-verified contravariance of
> argument types and covariance of return types. Consequently, they
> cannot support function subtyping. For example, if it requires code
> to convert an #int(Object) into an #int(String) and the result of the
> conversion is not reference-equal to the original value, then how
> would the compiler generate code to convert an Iterable<#int(Object)>
> into an Iterable<#int(String)>?
That's true that there is not currently support for function subtyping
but it can be added,
The EG of JSR292 let a place holder for that saying something like when
Java will suppport closure,
this need to be re-visited.
Also you can use invokedynamic and generate an inlining cache with an
entry for each runtime method type.
In both case, there is no conversion.
> Second, lambdas inside generic methods cannot in principle be reified
> if generic methods are not reified:
> *<T> #T() makeClosure(T t)*
> * return #()t; // what is the reified type of the closure here?*
First, we aren't in the same configuration than with the introduction of
there is no existing code that already use lambdas.
In my opinion the best way to deal with that code is to consider that
of a generic lambda is a conversion :
#String() fun = makeClosure("hello");
will be translated to something like:
#String() fun = makeClosure("hello").genericInstantiation(String.class);
Now to answer to your question, the reified type of a function type with
will be a function type with erasure of generics at place where there is
erasure of a type in a function type:
- if it's the return type and it is generic, use the type of null.
- if it's a parameter type and it is generic, use its bounds
- if it's not a generics, use it directly.
In you example, the reified function type will be #null()
I think it will be ok if cast between a generic function type and a
reified function type
(and vice-versa) are not allowed.
More information about the closures-dev