Multiple SAMs for same concept
Lawrence Kesteloot
lk at teamten.com
Thu Jul 15 17:00:15 PDT 2010
In addition, just because the signatures are identical doesn't mean
the contracts are identical. Provider.get(), for example, must never
return null, but who knows what Generator.op() might return? Same with
unchecked exceptions, allowed values of parameters, etc. The
programmer should be forced to explicitly convert from one to the
other (as in your "less than ideal" examples) to show that he has
consciously decided to treat the SAMs as compatible.
Lawrence
On Thu, Jul 15, 2010 at 4:49 PM, Pavel Minaev <int19h at gmail.com> wrote:
> On Thu, Jul 15, 2010 at 4:34 PM, Stephen Colebourne
> <scolebourne at joda.org> wrote:
>> One problem noted with the removal of function types is that multiple
>> SAMs with the same signature are not compatible. For example:
>>
>> http://gee.cs.oswego.edu/dl/jsr166/dist/extra166ydocs/extra166y/Ops.Generator.html
>> http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Supplier.html
>> http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/Provider.html
>>
>> Having these different incompatible definitions is problematic, for
>> example when the developer has created a library of reusable
>> implementations implementing one SAM, and then wants to use them using
>> another (eg. a newly added JDK SAM).
>>
>> Given the method:
>> private void process(Generator<String> gen) { ... }
>>
>> the most recent draft SotL would allow the following two choices for conversion:
>> Supplier<String> supplier = ...
>> process( {-> supplier.supply()} ); // manual conversion to a Generator
>> process( supplier#supply() ); // using method ref to manually
>> convert to Generator
>>
>> While the two solutions are not terrible, they are less than ideal. I
>> would argue that the ideal would be:
>> process(supplier); // auto-boxed from Supplier to Generator
>
> Such "autoboxing" (since no boxing happens here, I'd rather call it
> "autowrapping") wouldn't preserve object identity. I think it would be
> very confusing to pass a reference to object, only to receive a
> reference to a completely different (as in, r1 != r2) object on the
> other side - especially without any explicit casts or other indication
> that something unusual is going on.
>
> This wasn't a problem with primitives because they don't have their
> own object identity
>
>> One compromise option I came up with was:
>> process( supplier# );
>
> This looks more reasonable.
>
>
More information about the lambda-dev
mailing list