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