SAM identity or at least equals/hashCode
Ali Ebrahimi
ali.ebrahimi1781 at gmail.com
Tue Jun 21 23:37:36 PDT 2011
Hi,
yes, of course, i'm working on.
Ali Ebrahimi
On Tue, Jun 21, 2011 at 6:29 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> 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