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: https://bitbucket.org/atlassian
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 : JDK-8001642 : Add OptionalT, OptionalDouble, OptionalInt, OptionalLong
There is no need for an Option container to show how nested collections may be misused, you could just as easily show an example of a ListListListT that is isomorphic to a flattened IterableT . I'd simply point to the utility of the monadic bind or flatMap function! There are several reasons why Option types provide serious usability improvements over null, notwithstanding annotation support. The first is that the type-system prevents misuse (modulo unsafe API), and the second is that it allows operations that produce optional results to be sequenced easily without if checks. For mor information see previous posts on Optional forming a Monad. cheers, jed. On 06/03/2013, at 10:58 PM, Remi Forax fo...@univ-mlv.fr wrote: On 03/06/2013 11:54 AM, Jed Wesley-Smith wrote: Really, this is a lot of fuss over nothing. There is actually no fundamental difference between Scala's Option, Guava's Optional, Fugue's Option, Java's Optional and Haskell's Maybe – they are modelling the same thing, the possibility of a value not being present. The fact that there may be minor differences in api or semantics around whether null is a legal value are minor in the scheme of things (and yes, null is a pretty stupid legal value of a Some IMHO). Stephen's example is ludicrous, why have a list of optional values? You'd flatten down into just a list – and an optional list only makes sense if the enclosed list is guaranteed to be non-empty, otherwise you just return an empty list! People like shooting their own feet. http://cs.calstatela.edu/wiki/index.php/Courses/CS_460/Fall_2012/Week_8/gamePlay.combat.BattleAnalysis If we are going to use potential straw-men as arguments we can stall all progress. Please concentrate on the important matters, let's disavow null as a valid value and save us all a billion dollars Also Scala Option is not the only way to solve the null problem. The JSR308 annotation @Nullable/@NonNull are recognized by Eclipse and IntelliJ at least. . cheers, jed. cheers, Rémi On 06/03/2013, at 8:47 PM, Remi Forax fo...@univ-mlv.fr wrote: Ok, let be nuclear on this, There is no good reason to introduce OptionalT in java.util. It doen't work like Google's Guava Optional despite having the same name, it doesn't work like Scala's Option despite having a similar name, moreover the lambda pipeline face a similar issue with the design of collectors (see stream.collect()) but solve that similar problem with a different design, so the design of Optional is not even consistent with the rest of the stream API. So why do we want something like Optional, we want it to be able to represent the fact that as Mike states a returning result can have no value by example Colections.emptyList().stream().findFirst() should 'return' no value. As Stephen Colebourne said, Optional is a bad name because Scala uses Option [1] which can used in the same context, as result of a filter/map etc. but Option in Scala is a way to mask null. Given the name proximity, people will start to use Optional like Option in Scala and we will see methods returning things like OptionalListOptionalString. Google's Guava, which is a popular library, defines a class named Optional, but allow to store null unlike the current proposed implementation, this will generate a lot of confusions and frustrations. In fact, we don't need Optional at all, because we don't need to return a value that can represent a value or no value, the idea is that methods like findFirst should take a lambda as parameter letting the user to decide what value should be returned by findFirst if there is a value and if there is no value. So instead of stream.findFirst().orElse(null) you will write stream.findFirst(orNull) with orNull() defined as like that public static T Optionalizer orNull() { return (isPresent, element) - isPresent? element: null; } The whole design is explained here [2] and is similar to the way Collectors are defined [3], it's basically the lambda way of thinking, instead of creating an object representing the different states resulting of a call to findFirst, findFirst takes a lambda as parameter which is fed with the states of a call. cheers, Rémi [1] http://www.scala-lang.org/api/current/index.html#scala.Option [2] http://mail.openjdk.java.net/pipermail/lambda-libs-spec-observers/2013-February/001470.html [3] http://hg.openjdk.java.net/lambda/lambda/jdk/file/tip/src/share/classes/java/util/stream/Collectors.java On 03/04/2013 09:29 PM, Mike Duigou wrote: Hello All; This patch introduces Optional container objects to be used by the lambda streams libraries for returning results. The reference Optional type, as defined, intentionally does not allow null values. null may be used with the Optional.orElse() method. All of the Optional types define hashCode() and equals implementations. Use of Optional types
Re: RFR : JDK-8001642 : Add OptionalT, OptionalDouble, OptionalInt, OptionalLong
Really, this is a lot of fuss over nothing. There is actually no fundamental difference between Scala's Option, Guava's Optional, Fugue's Option, Java's Optional and Haskell's Maybe – they are modelling the same thing, the possibility of a value not being present. The fact that there may be minor differences in api or semantics around whether null is a legal value are minor in the scheme of things (and yes, null is a pretty stupid legal value of a Some IMHO). Stephen's example is ludicrous, why have a list of optional values? You'd flatten down into just a list – and an optional list only makes sense if the enclosed list is guaranteed to be non-empty, otherwise you just return an empty list! If we are going to use potential straw-men as arguments we can stall all progress. Please concentrate on the important matters, let's disavow null as a valid value and save us all a billion dollars. cheers, jed. On 06/03/2013, at 8:47 PM, Remi Forax fo...@univ-mlv.fr wrote: Ok, let be nuclear on this, There is no good reason to introduce OptionalT in java.util. It doen't work like Google's Guava Optional despite having the same name, it doesn't work like Scala's Option despite having a similar name, moreover the lambda pipeline face a similar issue with the design of collectors (see stream.collect()) but solve that similar problem with a different design, so the design of Optional is not even consistent with the rest of the stream API. So why do we want something like Optional, we want it to be able to represent the fact that as Mike states a returning result can have no value by example Colections.emptyList().stream().findFirst() should 'return' no value. As Stephen Colebourne said, Optional is a bad name because Scala uses Option [1] which can used in the same context, as result of a filter/map etc. but Option in Scala is a way to mask null. Given the name proximity, people will start to use Optional like Option in Scala and we will see methods returning things like OptionalListOptionalString. Google's Guava, which is a popular library, defines a class named Optional, but allow to store null unlike the current proposed implementation, this will generate a lot of confusions and frustrations. In fact, we don't need Optional at all, because we don't need to return a value that can represent a value or no value, the idea is that methods like findFirst should take a lambda as parameter letting the user to decide what value should be returned by findFirst if there is a value and if there is no value. So instead of stream.findFirst().orElse(null) you will write stream.findFirst(orNull) with orNull() defined as like that public static T Optionalizer orNull() { return (isPresent, element) - isPresent? element: null; } The whole design is explained here [2] and is similar to the way Collectors are defined [3], it's basically the lambda way of thinking, instead of creating an object representing the different states resulting of a call to findFirst, findFirst takes a lambda as parameter which is fed with the states of a call. cheers, Rémi [1] http://www.scala-lang.org/api/current/index.html#scala.Option [2] http://mail.openjdk.java.net/pipermail/lambda-libs-spec-observers/2013-February/001470.html [3] http://hg.openjdk.java.net/lambda/lambda/jdk/file/tip/src/share/classes/java/util/stream/Collectors.java On 03/04/2013 09:29 PM, Mike Duigou wrote: Hello All; This patch introduces Optional container objects to be used by the lambda streams libraries for returning results. The reference Optional type, as defined, intentionally does not allow null values. null may be used with the Optional.orElse() method. All of the Optional types define hashCode() and equals implementations. Use of Optional types in collections should be generally discouraged but having useful equals() and hashCode() is ever so convenient. http://cr.openjdk.java.net/~mduigou/JDK-8001642/0/webrev/ Mike