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