Typed Method handles
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Thu Jun 9 06:26:01 PDT 2011
On 09/06/11 14:19, Rémi Forax wrote:
> On 06/09/2011 12:33 PM, Ali Ebrahimi wrote:
>> Hi Remi,
>> comments inlined.
>>
>> On Thu, Jun 9, 2011 at 1:49 PM, Rémi Forax<forax at univ-mlv.fr
>> <mailto:forax at univ-mlv.fr>> wrote:
>>
>> 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.
>>
>> This is not so hard. Method handles are new phenoms to platform and
>> compiler can handle them specially as polymorphic signature method
>> invocations handed.
>>
>> Best Regards,
>> Ali Ebrahimi
>>
>> So this syntax was rejected for Java 8 but may be reconsidered later.
>>
>> Rémi
>>
> I think I know what a method handle is.
> Polymorphic signature method like MH.invoke or MH.invokeGeneric are handled
> by bypassing the method resolution used by the compiler.
> That's why you have to specify the return type when calling such methods.
> To summarize, the compiler does nothing and let the VM checks at runtime
> if the invocation is safe or not.
I confirm - the compiler simply keeps track of the actual types passed
to the PS method in order to generate a classfile attribute that
contains the 'inferred' signature for that PS call.
Maurizio
> So you can't reuse this mechanism to implement function type.
>
> 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