Typed Method handles
Rémi Forax
forax at univ-mlv.fr
Thu Jun 9 03:19:38 PDT 2011
On 06/09/2011 11:55 AM, Ali Ebrahimi wrote:
> Hi all,
> What happens if method handles takes variable arty of generic type
> parameters.
>
> MethodHandle<void,int> mh = #{x -> System.out.println(x);};
>
> mh.invokeExack(1); //compiles
>
> mh.invokeExack("1"); //compile fail
I've proposed this syntax last year or before.
There are 2 problems:
- it's a function type, so this means to introduce a new kind of type
in the Java type system.
- it allows to use void and the primitives types between the angle bracket
which is not something allowed for the generics syntax.
So this syntax was rejected for Java 8 but may be reconsidered later.
Rémi
>
> methodhandle is a special case and can take any number of type parameters
> including primitive and reference types.
>
> With this compiler can check types and number of method handle's
> invokeExack/invoke invocations.
> This only happens if declaration have generic type params.
>
> But how to pass this method handles as method args.
>
> I assume we have following method.
>
> class Test{
> static void test(MethodHandle<void,int> mh){
>
> }
> }
>
> Now I can pass above methodhandle as following to test method.
>
> Test.test(mh);
>
> But can i overload this method with another method handles that takes
> difference form of type parameters.
>
> Currently answer is No.
> So type parameters for MethodHandles in parameter declarations have little
> benefit and we can does not support that.
>
> Main problem for use of method handles is that they can not be saticaly
> checked by compiler for type safety.
>
> I think by specially handling of generic parameters for method handles can
> be solved (althogh, not completely).
>
> But what is other solution for passing method handles to other methods as
> args. This is SAM types.
>
> by assuming of follwing code:
>
> class Test{
> interface SAM{
> void m(int x);
> }
> static void test(SAM sam){
> }
> }
>
> MethodHandle<void,int> mh = #{x -> System.out.println(x);};
>
> Now can i pass this methodhandle directly to test method.
> Test.test(mh);
>
> abvuse answer is No at all. compiler rejects that.
>
> But how to turn of this type checking.
> My idea is intruducing of an empty compiler and jvm aware marker interface.
> and retrufit all Sam types with it.
>
> interface MHAware{ //Dynamic Or UnCheckedType Or StructurallyCheckable
> }
>
> And new version of SAM interface:
>
> interface SAM implements MHAware{
> void m(int x);
> }
>
> MethodHandle<void,int> mh = #{x -> System.out.println(x);};
> Test.test(mh);
> This time compiler only checks structural compatibility and does not do any
> conversion.
>
> MethodHandle<void,int> <-----> interface SAM implements MHAware{ void
> m(int x); }
>
> Therefore for following compile fails.
>
> MethodHandle<void,int,int> mh2 = #{x , y -> System.out.println(x+y);};
>
> Test.test(mh2); //compile error: MethodHandle<void,int> and SAM are not
> structurally compatible.
>
> Some Issues:
> 1) Sam types can be casted to methodhandles. MethodHandle<void,intt> mh =
> sam;
> ..
>
>
> But invocation on this types must be specialy handled by jvm and treated
> them as method handle (original type is MethodHandle);
>
> Alternative solution:
> generate a concreate class implementing Sam typea
> class SamImp implements Sam,MethodHandleAware{
> final MethodHandle<void,int> target;
> SamImp(MethodHandle<void,int> mh){ this.target = mh}
> MethodHandle<void,int> asMethodHandle(){ return this.target}
> void m(int x){ mh.invokeExact(x);}
> }
>
> Test.test(new SamImp(mh2));
>
>
> Final note: My main goal in this post is that lambdas purely implemented by
> method handles. And we don't have any overhead of Sam conversions (proxy
> objects and reflection).
>
> I think, i walk on clouds.
> What do you think?
>
>
> Best Regards
> Ali Ebrahimi
>
More information about the lambda-dev
mailing list