RFR: 8015317: Optional.filter, map, and flatMap

Zhong Yu zhong.j.yu at gmail.com
Mon Jul 15 02:52:56 UTC 2013


Another example of possible missing a wildcard

http://gee.cs.oswego.edu/dl/jsr166/dist/docs/java/util/concurrent/CompletionStage.html#thenCompose%28java.util.function.Function%29

   thenCompose(Function<? super T,? extends CompletionStage<U>> fn)

should be

   thenCompose(Function<? super T,? extends CompletionStage<? extends U>> fn)

The problem is probably wide spread, and we need a tool to find these mistakes.

Zhong Yu


On Sun, Jul 14, 2013 at 8:04 AM, Jed Wesley-Smith <jed at wesleysmith.io> wrote:
> (accidentally didn't post to the list)
>
>> You probably know that the example provided is not completed ported to
> work with our Optional implementation,
>
> It should be, for the example I wrote an Optional that is final and should
> be otherwise identical. It should certainly be fairly easy for any
> committer to try. If you can make it work without the ? extends Optional
> I'd love an explanation of how.
>
>> and fugue works around the type system with Option as abstract class.
>
> As I've tried to explain, this isn't about the implementation of the
> container class, but how covariance works with a parameterised class.
>
> We originally had the non-, but in a discussion with Brian he alerted us to
> the fact that the signature was wrong. We hastily fixed it:
>
> https://bitbucket.org/atlassian/fugue/commits/9eca663326a5baeb8f23974732ec585d5627a05c
>
> To further demonstrate, I give you a minimal example of a final Optional
> implementation that does not compile for this test:
>
> https://gist.github.com/jedws/5993596#file-gistfile1-java-L57
>
> cheers,
> jed.
>
>
>
> On 14 July 2013 15:02, Henry Jen <henry.jen at oracle.com> wrote:
>
>>  I think I understand what you are saying. However, unless we make
>> Optional not final, the extends part just doesn't matter.
>>
>> You probably know that the example provided is not completed ported to
>> work with our Optional implementation, and fugue works around the type
>> system with Option as abstract class.
>>
>> Cheers,
>> Henry
>>
>>  On Jul 13, 2013, at 4:35 PM, Jed Wesley-Smith <jed at wesleysmith.io><jed at wesleysmith.io>wrote:
>>
>>  I did supply a test that you can use to try it.
>>
>>  What we are talking about is whether type Box<Parent> is substitutable
>> by Box<Child> in the contravariant position. Intuitively we think we only
>> need Box<? extends Parent> because we only care about the type parameter,
>> but the type – as you point out – is actually different. Box<Parent> is not
>> "inherited by" Box<Child>.
>>
>>  Specifically, if we have a consuming Box, and we replace it with a Box
>> of a more specific type parameter, we could attempt feed the more general
>> type into it, ie. a Box<Child> isn't going to appreciate having Parent fed
>> to it. This is why covariance and mutable containers don't mix well, and
>> why Java's covariant arrays are problematic.
>>
>>  In this situation we have an immutable container, and we can substitute
>> the type of our container with one of a more specific type, as it will only
>> ever supply a value – and a value of Child will suffice as a Parent. So,
>> for this case we need a Box that is substitutable, and therefore we need to
>> add the covariance to our box.
>>
>>  <? extends Box> is simply adding covariance to our Box type.
>>
>>  For a much better explanation than I can give about this, see this
>> excellent post describing generics in Scala, which – apart from have
>> declaration-site variance and using [A] in place of <A> – generally follow
>> the same pattern:
>>
>>
>> http://termsandtruthconditions.herokuapp.com/blog/2012/12/29/covariance-and-contravariance-in-scala/
>>
>>  cheers,
>> jed.
>>
>>
>> On 14 July 2013 04:49, Henry Jen <henry.jen at oracle.com> wrote:
>>
>>> I think the type you talking about here is Optional<? extends U> instead
>>> of ? extends Optional<U>.
>>>
>>>  IIRC, Optional<? extends U> is not a subtype of Optional<U>, just like
>>> any other Collection class. List<Child> is not a List<Parent>.
>>>
>>>  Cheers,
>>> Henry
>>>
>>>
>>>  On Jul 13, 2013, at 3:15 AM, Jed Wesley-Smith <jed at wesleysmith.io>
>>> wrote:
>>>
>>>  > The ? extends Optional is unnecessary in flatMap as Optional is final.
>>>
>>>  interestingly enough, it actually is.
>>>
>>>  try the following test:
>>>
>>>  class OptionalTest {
>>>   class Parent {};
>>>
>>>    class Child extends Parent {};
>>>
>>>    @Test public void covariantReturn() {
>>>     Optional<Parent> some = some(new Parent());
>>>     Function<Parent, Optional<Child>> f = new Function<Parent,
>>> Optional<Child>>() {
>>>       @Override public Optional<Child> apply(Parent p) {
>>>         return some(new Child());
>>>       }
>>>     };
>>>     Optional<Parent> mapped = some.<Parent> flatMap(f);
>>>     assertThat(mapped.get(), notNullValue());
>>>   }
>>> }
>>>
>>>  adapted from the fugue test suite:
>>>
>>>
>>> https://bitbucket.org/atlassian/fugue/src/96a65067fb7aaf1edae1bffa07167a5865cbebec/src/test/java/com/atlassian/fugue/OptionTest.java#cl-155
>>>
>>>  The point to remember is that Optional<Child> is a type and as such is
>>> actually a subtype of Optional<Parent> –  and therefore requires a
>>> covariant return.
>>>
>>>  cheers,
>>> jed.
>>>
>>>
>>>
>>>
>>> On 13 July 2013 04:15, Mike Duigou <mike.duigou at oracle.com> wrote:
>>>
>>>> The ? extends Optional is unnecessary in flatMap as Optional is final.
>>>> Otherwise this looks good.
>>>>
>>>> Mike
>>>>
>>>> On Jul 5 2013, at 14:37 , Henry Jen wrote:
>>>>
>>>> > Hi,
>>>> >
>>>> > Please review the webrev at
>>>> >
>>>> > http://cr.openjdk.java.net/~henryjen/ccc/8015317.0/webrev/
>>>> >
>>>> > Which adds following method to Optional,
>>>> >
>>>> > public static <T> Optional<T> ofNullable(T value) {}
>>>> > public Optional<T> filter(Predicate<? super T> predicate) {}
>>>> > public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {}
>>>> > public<U> Optional<U> flatMap(Function<? super T, ? extends
>>>> Optional<U>>
>>>> > mapper) {}
>>>> >
>>>> > Also included is some cleanup on javadoc.
>>>> >
>>>> > Cheers,
>>>> > Henry
>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>



More information about the core-libs-dev mailing list