SAM identity or at least equals/hashCode
Ali Ebrahimi
ali.ebrahimi1781 at gmail.com
Tue Jun 21 07:20:39 PDT 2011
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>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