deduplicating lambda methods

Liam Miller-Cushon cushon at google.com
Mon Mar 5 20:22:18 UTC 2018


On Mon, Mar 5, 2018 at 3:30 AM, Maurizio Cimadamore <
maurizio.cimadamore at oracle.com> wrote:

>
> On 05/03/18 07:51, Tagir Valeev wrote:
>
>> Hello!
>>
>>   E.g. when diffing the lambda bodies for `s -> s` and `x -> x` it sees
>>>
>> that
>> `s` and `x` are both the first parameter of their enclosing lambdas.
>>
>> By the way how types are matched? I assume that you won't merge `s -> s`
>> and `x -> x`
>> if `s` is String and `x` is an int, right? However merging two lambdas
>> like
>> `s -> true` and `sb -> true`
>> where `s` is a String and `sb` is a StringBuilder seems possible (creating
>> a synthetic method which
>> receives an Object).
>>
> Yes, if parameters are unused, then I'd expect that an AST diff will just
> say that the body is the same for both.
>
> Also two lambdas like `list -> list.size()` can be
>> merged if the parameter types
>> differ in type parameters (e.g. List<String> and List<Integer>), but have
>> the same erasure.
>>
> Yes, the diff should work on erased types, which is what really matters in
> terms of bytecode generation. There are of course caveat - if you call
> List::get instead of List::size, then you can get extra synthetic casts,
> and, in that case, you need to avoid deduplication so that each lambda can
> have its own synthetic cast.


The initial proposal was to deduplicate lambdas that (1) implement the same
functional interface, (2) capture the same state, and (3) have the same
implementation. The diff is used specifically to determine (3), and (1)
guarantees that the parameter types match.

So deduplicating e.g. `(String s) -> true` and `(StringBuilder s) -> true`
is something that could be investigated, but it isn't currently handled.


More information about the amber-dev mailing list