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