MethodHandle vs function types

Neal Gafter neal at gafter.com
Sun Feb 21 22:25:31 PST 2010


When function types are represented as generic interfaces, as in BGGA, the
generated implementation must cast each reference argument from Object (the
type of the argument in the function's erased type) to the declared type of
the lambda argument.  For example, in the lambda expression

#(Integer i) (i)

the bytecode for the body of this lambda must do something like this

#(Object _i) {
  Integer i = (Integer)_i;  // copy the erased parameter to a variable with
the proper type
  return i;
}

Similarly, values received from a lambda invocation must be cast by the
caller to the return type of the function.  For example, this

#Integer() function = ...;
Integer x = function.();

would be translated in the generated bytecode to something like this

#Object() function = ...;
Integer x = (Integer)function.();

These translations are described in the JLS and were implemented in JDK5 as
part of the "erasure" scheme for generics.

Some people are displeased about these casts (and their performance impact)
remaining in the code, and would like the implementation of project lambda
to avoid them.  One approach that has been suggested is erasing function
types to MethodHandle instead of interfaces.  Unfortunately, MethodHandle
does not implement the subtyping scheme for values of function type.  That
necessitates one of three approaches.  Either (1) code is used to implement
the subtype conversion, or (2) the same erasure scheme that would have been
used with interfaces be used with MethodHandle (the method handle uses
Object in place of all reference types), or (3) the MethodHandle primitive
be relaxed to support the function subtying scheme.

Approach (1) doesn't work for various reasons.  As we've already seen by the
failure of Howard Lovatt's attempt to reify function types, we must preserve
reference identity for all widening reference conversions.

Approach (2) retains the very disadvantage that MethodHandle was meant to
solve.  Of course, MethodHandle may come with other advantages that make it
still worth using.

Approach (3) is outside the scope of project lambda to address (it is an
issue for jsr292), but I think it would be a very good idea for us to
encourage them to work on it.

Cheers,
Neal


More information about the lambda-dev mailing list