conversion between functional interfaces
Remi Forax
forax at univ-mlv.fr
Tue Feb 25 00:23:42 PST 2014
for the syntactic part, you can use a method reference
call(b::b)
so i don't think we need more magic.
At runtime, the main issue is that because of the conversion a constant lambda is not constant anymore. We may create a special case for that but we have decided to wait and see if this pattern will be frequent enough to worth the extra complexity.
Cheers,
Remi
From my smartphone
-------- Message d'origine --------
De : "Rafkind, Jon" <jon.rafkind at hp.com>
Date : 25/02/2014 3:09 (GMT+01:00)
A : lambda-dev at openjdk.java.net
Objet : conversion between functional interfaces
Functional interfaces with congruent signatures do not convert to each
other so lambda's cannot be directly passed between modules that define
their own lambda interfaces. Probably this issue was brought up
somewhere but I couldn't find it. Is it something that will be addressed
for Java 9?
public class Test{
public void call(A a){
}
public void test(){
B b = (s) -> 2;
call(b); // fails
call((s) -> b.b(s)); // ok, eta-convert
}
}
interface A{
int a(String s);
}
interface B{
int b(String s);
}
In this code, A and B are the same for all intents and purposes. Right
now the 'call' method only accepts functions of type 'A', but it could
just as easily accept functions of type 'B'. To pass a 'B' to 'call' we
have to wrap it in an extra lambda which simply passes along its arguments.
I don't have a concrete use-case where this is an issue, it was just an
issue raised in a private discussion.
It would be nice if either
1. the compiler automatically eta-converted lambda expressions for me as
in the second invocation of 'call'
2. some internal magic would allow a 'B' value to be used where an 'A'
type was expected. I don't know if this is possible but it seems like
the best case because it would hopefully not incur the cost of the extra
method invocation of 'b.b'
Off the top of my head 1 seems easy enough to implement. Given an
expression of type S, if S is a functional interface, and a matching
parameter with a formal type T, where T is a functional interface, if
the function types of S and T are congruent then replace the expression
with a new lambda expression with the same number of parameters as the
function type whose body invokes the expression with the new parameters.
More information about the lambda-dev
mailing list