SAM identity or at least equals/hashCode

Peter Levart peter.levart at marand.si
Tue Jun 21 02:16:09 PDT 2011


On 06/20/11, Brian Goetz wrote:
> I think "lambda expression" is the right thing to say when you are 
> referring to the lambda itself.  It is an expression, but its type is 
> contingent on its context (it is target-typed) and undergoes a 
> conversion of sorts before it becomes a SAM.
> 
> If you want to refer to the object instance that is the result of SAM 
> conversion, call that the SAM instance or the SAM object -- which is an 
> object.  (You can't assume much about its identity -- the compiler will 
> likely make sure that all instances of "stateless" lambdas are really 
> the same object, a la the "Flyweight" pattern.)
> 

Only stateless? Why?

I might have missed that and I'm sure there has been discussion already on this list about the topic, but it was a long time ago. So I thought to ask whether there are any news.

The question is: Will SAM objects that lambda expressions are going to be converted to, implement any meaningfull equals/hashCode methods or are those methods going to be inherited from Object (or SAM class).

The 0.1 spec document (http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/20100122/3764c21a/attachment.txt) defines SAM types as class OR interface type. For class type it says:

"If a SAM type is a class type, then it must be declared abstract and have a no-args constructor."

If the restriction for SAM class types was a little stronger:

"If a SAM type is a class type, then it must be declared abstract and have a no-args constructor. Furthermore if the SAM class or any of it's superclasses (except Object) overrides equals() and or hashCode() methods, then those methods mut not be declared final."

With such a restriction it would be possible for runtime to create SAM objects with meaningfull equals/hashCode methods. It would be possible to define semantics of the equals/hasCode methods in terms of:

a) the equals/hashCode methods of the SAM class (if it was a class that overrides Object.equals/HashCode)
b) the equals/hashCode methods of the references captured by the lambda
c) the identity of the code that is used as the code that executes lambda body.

because we know that current lambda prototype uses MethodHandles as a mechanism for capturing the environment and linking the compiler-generated method that executes the lambda body with the captured state and SAM object, there would have to be some support from MethodHandle. Idealy MethodHandle could already implement hashCode/equals methods of the correct semantics and the runtime generated SAM object would just delegate to the top-most MethodHandle for b) and c) and possibly to SAM's hashCode()/equals() for a).

To clarify c) - I think that the identity of the code that executes lambda body could simply be equated to the lexical instance of the lambda body as it apears in the source code. I think that each such lexical instance is translated by the compiler into a separate method and the identity of the method could be compared by the corresponding MethodHandle's equals/hashCode.

Current Javadoc API for MethodHandle says that it's hashCode/equals methods are inherited from Object.

Would any such scheme which defined meaningfull hashCode/equals for MethodHandles prevent optimizations that are implemented or planned for them or are there any other issues (besides lack of time) to implement such scheme?

There are a lot of use cases where having meaningfull equals/hashCode on an object enables using lambda expressions (and/or method references) in contexts where without such scheme the programmer would have to implement this on it's own and outside the lambda expressions translated to SAM instances which would make code more awkward.

Regards, Peter


More information about the lambda-dev mailing list