SAM identity or at least equals/hashCode

Brian Goetz brian.goetz at oracle.com
Tue Jun 21 07:59:59 PDT 2011


Care to share your translation strategy?

On 6/21/2011 10:48 AM, Ali Ebrahimi wrote:
> Hi, I know that.
>
> I think we can convert  all statefull lambdas to stateless ones in
> desugering phase.
>
> Ali ebrahimi
>
> On Tue, Jun 21, 2011 at 5:57 PM, Brian Goetz <brian.goetz at oracle.com
> <mailto:brian.goetz at oracle.com>> wrote:
>
>     The compiler desugars the lambda to a method that has two
>     parameters. SAM converting that method to one that has no parameters
>     can be accomplished in a number of ways -- generating bytecode for
>     the method that does the currying, MethodHandle.insertArguments, etc.
>
>
>     On 6/21/2011 10:20 AM, Ali Ebrahimi wrote:
>
>         Hi,
>         how do you handle it if you have more than one captured (bound)
>         state?
>
>         public Adder adderGenerator(int x, int y) { return #{ ->  x + y} };
>
>         Ali Ebrahimi
>         On Tue, Jun 21, 2011 at 5:36 PM, Peter
>         Levart<peter.levart at marand.si
>         <mailto:peter.levart at marand.si>>__wrote:
>
>             On 06/21/11, Brian Goetz wrote:
>
>                         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?
>
>
>                 Lambdas can capture final local variables.  Consider:
>
>                 public IntFactory constGenerator(int x) { return #{ ->
>                   x } };
>
>
>             This is exactly the use case I'm talking about. One would
>             want that
>
>             constGenerator(12).equals(__constGenerator(12)) would
>             evaluate to true and
>             constGenerator(12).equals(__constGenerator(13)) would
>             evaluate to false
>
>             event though the instances of two SAM objects returned from
>             two invocations
>             of method:
>
>             constGenerator(12)
>
>             are not the same instance, they could be equal.
>
>                 Clients will call the resulting IntFactory with
>                     foo.make()
>                 and expect an int to come back.  The SAM-converted
>                 lambda is an object,
>                 it has to have a nilary make() method, that method has
>                 captured state x,
>                 so where do we store the captured state?
>
>
>             I belive you (could) generate a static method with one
>             formal parameter:
>
>             private static int lambda$1(Integer p1) { return p1; }
>
>             ...then obtain a MethodHandle for it, say: lambda$1Mh
>             ...then capture the final x: lambda$1BoundMh =
>             lambda$1Mh.bindTo(x);
>
>             now the SAM-converted lambda object has a reference to
>             lambda$1BoundMh. It
>             uses it to delegate the invocation of it's nilary make()
>             method to. So why
>             could it not use it to delegate equals/hashCode methods too? The
>             prerequisite is of course that MethodHandle(s) define
>             meaningfull
>             equals/hashCode methods that take into account the captured
>             (bound) state
>             and any final target method identity too. That's what I had
>             in mind.
>
>             For the above example, lambda$1BoundMh would implement
>             equals/hashCode in
>             terms of delegating to bound Object (Integer in our case)
>             and to the wrapped
>             MH lambda$1Mh. The final lambda$1Mh would implement
>             equals/hashCode in terms
>             of target lambda$1 method signature.
>
>             Now, I don't know much about MHs and how they are
>             implemented and optimized
>             in the VM, so perhaps such scheme would defeat those
>             optimizations. Or is it
>             still possible?
>
>             Regards, Peter
>
>
>
>
>
>


More information about the lambda-dev mailing list