Pattern matching for java.util.Optional

Brian Goetz brian.goetz at oracle.com
Fri Jan 26 17:09:16 UTC 2024


It is not currently allowed, being discussed on a-s-e.

On 1/26/2024 11:17 AM, Nathan Reynolds wrote:
> Am I understanding this correctly or are we throwing an idea out 
> there?  Is the following legal today in Java 21?
>
>     switch (o) {
>         case Optional.of(var e): ...
>         case Optional.empty(): ...
>     }
>
> On Fri, Jan 26, 2024 at 6:28 AM Brian Goetz <brian.goetz at oracle.com> 
> wrote:
>
>     Let's step back, because your question is caught up in the details
>     of a solution, rather than focusing on the problem.
>
>     Obviously we want to be able to pattern match on Optional.  You've
>     gone down the road of "We have pattern matching for ADTs, so let's
>     turn Optional into an ADT, and then pattern match on that", and
>     then got caught in the details of whether this is a compatible
>     refactoring.
>
>     But I don't think we have to, or should, refactor the
>     representation to "match" the pattern machinery.  As outlined in
>     "Towards Member Patterns" and "Patterns in the Object Model", we
>     want to use the same tools for destructuring as we do for
>     aggregation.  Optional is assembled with static factories; we
>     should be able to take it apart with static patterns:
>
>         switch (o) {
>             case Optional.of(var e): ...
>             case Optional.empty(): ...
>         }
>
>     Adding `Some` and `None` deconstruction patterns would work, but
>     then we lose the correspondence between "how we put it together"
>     and "how we take it apart."  So I don't want to go down this
>     road.  (Another reason to not go down this road is that we want
>     Optional to work as a value type, which means one implementation.)
>
>     There are a few details yet to be wrapped up (e.g., how do we
>     denote the of/empty pair as exhaustive).
>
>     On 1/26/2024 2:30 AM, Red IO wrote:
>>     Now that pattern matching is nearly complete I was thinking about
>>     the distinction how the option type of the jdk works.
>>     What I'm talking about is the split between checking if it's
>>     empty and retrieving the value.
>>     Sure there are ways to transform the optional and GetOrElse and
>>     Throw varients. But none of them express the connection between
>>     isPresent and get:
>>     var option = Optional.of("Foo");
>>     if (option.isPresent()) {
>>     var foo = option.get();
>>     }
>>     Now pattern matching comes into play. A great solution that is
>>     used by many other languages to deal with the option type is
>>     matching rather or not it's present and in the same step
>>     providing the value to the valid code block. Something like this:
>>     var option = Optional.of("Foo");
>>     switch(option) {
>>     case Some(foo) -> {}
>>     case None() -> {}
>>     }
>>     Or
>>     if(option instanceof Some(foo) {
>>
>>     }
>>
>>     This is indeed possible in the current version of java using
>>     sealed types, records and pattern matching.
>>     Now it's sad that Optional was introduced before the features we
>>     have now where available and introducing a second option type
>>     would be confusing and terrible for apis.
>>
>>     But I don't think all hope is lost yet. I'm not too familiar with
>>     binary compatibility but from an api standpoint it would not
>>     change the public api of optional if it was turned from a final
>>     class into a sealed interface with 2 inner records representing
>>     the 2 states of the Optional instead of a nullable field. This
>>     way the public api of optional would just be added 2 inner types
>>     and otherwise stay the same.
>>
>>     I would love to hear your feedback on this one.
>>
>>     Great regards
>>     RedIODev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20240126/fdc62ea3/attachment.htm>


More information about the amber-dev mailing list