Re: RFR: 8015317: Optional.filter, map, and flatMap
I guess your methods should return BoxA to be comparable to Stream/Optional/CompletionStage cases. On Mon, Jul 15, 2013 at 2:17 AM, Jed Wesley-Smith j...@wesleysmith.io wrote: ignore me, you do actually need both ? extends on the type constructor and the inner type – dunno what I was thinking. On 15 July 2013 13:02, Jed Wesley-Smith j...@wesleysmith.io wrote: I'm not entirely sure that is a problem, have a look at the following: https://gist.github.com/jedws/5993596#file-variancetest-java it is only the one with a covariance annotation on the parameter that fails… On 15 July 2013 12:52, Zhong Yu zhong.j...@gmail.com wrote: 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 CompletionStageU 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 j...@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@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 j...@wesleysmith.ioj...@wesleysmith.iowrote: I did supply a test that you can use to try it. What we are talking about is whether type BoxParent is substitutable by BoxChild 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. BoxParent is not inherited by BoxChild. 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 BoxChild 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@oracle.com wrote: I think the type you talking about here is Optional? extends U instead of ? extends OptionalU. IIRC, Optional? extends U is not a subtype of OptionalU, just like any other Collection class. ListChild is not a ListParent. Cheers, Henry On Jul 13, 2013, at 3:15 AM, Jed Wesley-Smith j...@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() { OptionalParent some =
Re: RFR: 8015317: Optional.filter, map, and flatMap
I did supply a test that you can use to try it. What we are talking about is whether type BoxParent is substitutable by BoxChild 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. BoxParent is not inherited by BoxChild. 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 BoxChild 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@oracle.com wrote: I think the type you talking about here is Optional? extends U instead of ? extends OptionalU. IIRC, Optional? extends U is not a subtype of OptionalU, just like any other Collection class. ListChild is not a ListParent. Cheers, Henry On Jul 13, 2013, at 3:15 AM, Jed Wesley-Smith j...@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() { OptionalParent some = some(new Parent()); FunctionParent, OptionalChild f = new FunctionParent, OptionalChild() { @Override public OptionalChild apply(Parent p) { return some(new Child()); } }; OptionalParent 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 OptionalChild is a type and as such is actually a subtype of OptionalParent – and therefore requires a covariant return. cheers, jed. On 13 July 2013 04:15, Mike Duigou mike.dui...@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 OptionalT ofNullable(T value) {} public OptionalT filter(Predicate? super T predicate) {} publicU OptionalU map(Function? super T, ? extends U mapper) {} publicU OptionalU flatMap(Function? super T, ? extends OptionalU mapper) {} Also included is some cleanup on javadoc. Cheers, Henry
Re: RFR: 8015317: Optional.filter, map, and flatMap
I'm not entirely sure that is a problem, have a look at the following: https://gist.github.com/jedws/5993596#file-variancetest-java it is only the one with a covariance annotation on the parameter that fails… On 15 July 2013 12:52, Zhong Yu zhong.j...@gmail.com wrote: 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 CompletionStageU 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 j...@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@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 j...@wesleysmith.io j...@wesleysmith.iowrote: I did supply a test that you can use to try it. What we are talking about is whether type BoxParent is substitutable by BoxChild 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. BoxParent is not inherited by BoxChild. 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 BoxChild 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@oracle.com wrote: I think the type you talking about here is Optional? extends U instead of ? extends OptionalU. IIRC, Optional? extends U is not a subtype of OptionalU, just like any other Collection class. ListChild is not a ListParent. Cheers, Henry On Jul 13, 2013, at 3:15 AM, Jed Wesley-Smith j...@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() { OptionalParent some = some(new Parent()); FunctionParent, OptionalChild f = new FunctionParent, OptionalChild() { @Override public OptionalChild apply(Parent p) { return some(new Child()); } }; OptionalParent mapped = some.Parent flatMap(f); assertThat(mapped.get(), notNullValue()); } } adapted from the fugue test suite:
Re: RFR: 8015317: Optional.filter, map, and flatMap
(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@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 j...@wesleysmith.ioj...@wesleysmith.iowrote: I did supply a test that you can use to try it. What we are talking about is whether type BoxParent is substitutable by BoxChild 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. BoxParent is not inherited by BoxChild. 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 BoxChild 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@oracle.com wrote: I think the type you talking about here is Optional? extends U instead of ? extends OptionalU. IIRC, Optional? extends U is not a subtype of OptionalU, just like any other Collection class. ListChild is not a ListParent. Cheers, Henry On Jul 13, 2013, at 3:15 AM, Jed Wesley-Smith j...@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() { OptionalParent some = some(new Parent()); FunctionParent, OptionalChild f = new FunctionParent, OptionalChild() { @Override public OptionalChild apply(Parent p) { return some(new Child()); } }; OptionalParent 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 OptionalChild is a type and as such is actually a subtype of OptionalParent – and therefore requires a covariant return. cheers, jed. On 13 July 2013 04:15, Mike Duigou mike.dui...@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 OptionalT ofNullable(T value) {} public OptionalT filter(Predicate? super T predicate) {} publicU OptionalU map(Function? super T, ? extends U mapper) {} publicU OptionalU flatMap(Function? super T, ? extends OptionalU mapper) {} Also included is some
Re: RFR: 8015317: Optional.filter, map, and flatMap
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() { OptionalParent some = some(new Parent()); FunctionParent, OptionalChild f = new FunctionParent, OptionalChild() { @Override public OptionalChild apply(Parent p) { return some(new Child()); } }; OptionalParent 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 OptionalChild is a type and as such is actually a subtype of OptionalParent – and therefore requires a covariant return. cheers, jed. On 13 July 2013 04:15, Mike Duigou mike.dui...@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 OptionalT ofNullable(T value) {} public OptionalT filter(Predicate? super T predicate) {} publicU OptionalU map(Function? super T, ? extends U mapper) {} publicU OptionalU flatMap(Function? super T, ? extends OptionalU mapper) {} Also included is some cleanup on javadoc. Cheers, Henry
Re: RFR: 8015317: Optional.filter, map, and flatMap
ignore me, you do actually need both ? extends on the type constructor and the inner type – dunno what I was thinking. On 15 July 2013 13:02, Jed Wesley-Smith j...@wesleysmith.io wrote: I'm not entirely sure that is a problem, have a look at the following: https://gist.github.com/jedws/5993596#file-variancetest-java it is only the one with a covariance annotation on the parameter that fails… On 15 July 2013 12:52, Zhong Yu zhong.j...@gmail.com wrote: 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 CompletionStageU 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 j...@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@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 j...@wesleysmith.io j...@wesleysmith.iowrote: I did supply a test that you can use to try it. What we are talking about is whether type BoxParent is substitutable by BoxChild 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. BoxParent is not inherited by BoxChild. 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 BoxChild 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@oracle.com wrote: I think the type you talking about here is Optional? extends U instead of ? extends OptionalU. IIRC, Optional? extends U is not a subtype of OptionalU, just like any other Collection class. ListChild is not a ListParent. Cheers, Henry On Jul 13, 2013, at 3:15 AM, Jed Wesley-Smith j...@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() { OptionalParent some = some(new Parent()); FunctionParent, OptionalChild f = new FunctionParent, OptionalChild() { @Override public OptionalChild apply(Parent p) { return some(new Child()); }
Re: RFR: 8015317: Optional.filter, map, and flatMap
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 j...@wesleysmith.io wrote: I did supply a test that you can use to try it. What we are talking about is whether type BoxParent is substitutable by BoxChild 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. BoxParent is not inherited by BoxChild. 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 BoxChild 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@oracle.com mailto:henry@oracle.com wrote: I think the type you talking about here is Optional? extends U instead of ? extends OptionalU. IIRC, Optional? extends U is not a subtype of OptionalU, just like any other Collection class. ListChild is not a ListParent. Cheers, Henry On Jul 13, 2013, at 3:15 AM, Jed Wesley-Smith j...@wesleysmith.io mailto:j...@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() { OptionalParent some = some(new Parent()); FunctionParent, OptionalChild f = new FunctionParent, OptionalChild() { @Override public OptionalChild apply(Parent p) { return some(new Child()); } }; OptionalParent 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 OptionalChild is a type and as such is actually a subtype of OptionalParent – and therefore requires a covariant return. cheers, jed. On 13 July 2013 04:15, Mike Duigou mike.dui...@oracle.com mailto:mike.dui...@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/ http://cr.openjdk.java.net/%7Ehenryjen/ccc/8015317.0/webrev/ Which adds following method to Optional, public static T OptionalT ofNullable(T value) {} public OptionalT filter(Predicate? super T predicate) {} publicU OptionalU map(Function? super T, ? extends U mapper) {} publicU OptionalU flatMap(Function? super T, ? extends OptionalU mapper) {} Also included is some cleanup on javadoc. Cheers, Henry
Re: RFR: 8015317: Optional.filter, map, and flatMap
I think the type you talking about here is Optional? extends U instead of ? extends OptionalU. IIRC, Optional? extends U is not a subtype of OptionalU, just like any other Collection class. ListChild is not a ListParent. Cheers, Henry On Jul 13, 2013, at 3:15 AM, Jed Wesley-Smith j...@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() { OptionalParent some = some(new Parent()); FunctionParent, OptionalChild f = new FunctionParent, OptionalChild() { @Override public OptionalChild apply(Parent p) { return some(new Child()); } }; OptionalParent 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 OptionalChild is a type and as such is actually a subtype of OptionalParent – and therefore requires a covariant return. cheers, jed. On 13 July 2013 04:15, Mike Duigou mike.dui...@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 OptionalT ofNullable(T value) {} public OptionalT filter(Predicate? super T predicate) {} publicU OptionalU map(Function? super T, ? extends U mapper) {} publicU OptionalU flatMap(Function? super T, ? extends OptionalU mapper) {} Also included is some cleanup on javadoc. Cheers, Henry
Re: RFR: 8015317: Optional.filter, map, and flatMap
XYChild is not a subtype of XY? extends Parent. We have to go wildcard all the way - X? extends Y? extends Parent. The subtyping rules don't care about final-ness of types. For example, XString is a distinct type from X? extends String, even though String has only one subtype (itself). Zhong Yu On Sun, Jul 14, 2013 at 8:04 AM, Jed Wesley-Smith j...@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@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 j...@wesleysmith.ioj...@wesleysmith.iowrote: I did supply a test that you can use to try it. What we are talking about is whether type BoxParent is substitutable by BoxChild 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. BoxParent is not inherited by BoxChild. 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 BoxChild 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@oracle.com wrote: I think the type you talking about here is Optional? extends U instead of ? extends OptionalU. IIRC, Optional? extends U is not a subtype of OptionalU, just like any other Collection class. ListChild is not a ListParent. Cheers, Henry On Jul 13, 2013, at 3:15 AM, Jed Wesley-Smith j...@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() { OptionalParent some = some(new Parent()); FunctionParent, OptionalChild f = new FunctionParent, OptionalChild() { @Override public OptionalChild apply(Parent p) { return some(new Child()); } }; OptionalParent 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 OptionalChild is a type and as such is actually a subtype of OptionalParent – and therefore requires a covariant return. cheers, jed. On 13 July 2013 04:15, Mike Duigou mike.dui...@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
Re: RFR: 8015317: Optional.filter, map, and flatMap
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 CompletionStageU 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 j...@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@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 j...@wesleysmith.ioj...@wesleysmith.iowrote: I did supply a test that you can use to try it. What we are talking about is whether type BoxParent is substitutable by BoxChild 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. BoxParent is not inherited by BoxChild. 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 BoxChild 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@oracle.com wrote: I think the type you talking about here is Optional? extends U instead of ? extends OptionalU. IIRC, Optional? extends U is not a subtype of OptionalU, just like any other Collection class. ListChild is not a ListParent. Cheers, Henry On Jul 13, 2013, at 3:15 AM, Jed Wesley-Smith j...@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() { OptionalParent some = some(new Parent()); FunctionParent, OptionalChild f = new FunctionParent, OptionalChild() { @Override public OptionalChild apply(Parent p) { return some(new Child()); } }; OptionalParent 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 OptionalChild is a type and as such is actually a subtype of OptionalParent – and therefore requires a covariant return. cheers, jed. On 13 July 2013 04:15, Mike Duigou mike.dui...@oracle.com wrote: The ? extends Optional is unnecessary in flatMap as Optional is
Re: RFR: 8015317: Optional.filter, map, and flatMap
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 OptionalT ofNullable(T value) {} public OptionalT filter(Predicate? super T predicate) {} publicU OptionalU map(Function? super T, ? extends U mapper) {} publicU OptionalU flatMap(Function? super T, ? extends OptionalU mapper) {} Also included is some cleanup on javadoc. Cheers, Henry
Re: RFR: 8015317: Optional.filter, map, and flatMap
On Jul 5, 2013, at 11:37 PM, Henry Jen henry@oracle.com wrote: Hi, Please review the webrev at http://cr.openjdk.java.net/~henryjen/ccc/8015317.0/webrev/ Looks OK to me. Paul. Which adds following method to Optional, public static T OptionalT ofNullable(T value) {} public OptionalT filter(Predicate? super T predicate) {} publicU OptionalU map(Function? super T, ? extends U mapper) {} publicU OptionalU flatMap(Function? super T, ? extends OptionalU mapper) {} Also included is some cleanup on javadoc. Cheers, Henry