Pattern matching for java.util.Optional

David Alayachew davidalayachew at gmail.com
Fri Jan 26 15:51:23 UTC 2024


Hello RedIODev,

It is absolutely a good strategy.

Sealed types are Java's tagged unions (or sum types, further reading here
-- https://en.wikipedia.org/wiki/Tagged_union). And tagged unions are a
form of union types. Anything you would want a union type for, a sealed
type should fit the bill cleanly.

Did you have a particular concern about using them that makes them look
like a potential anti-pattern?

Thank you for your time!
David Alayachew

On Fri, Jan 26, 2024 at 9:43 AM Red IO <redio.development at gmail.com> wrote:

> I wasn't aware of the plan to support that kind of pattern matching in the
> future. Of course this is a way better and less disruptive way of doing it.
> Thanks for the insightful answer.
>
> One more thing what is your opinion on the sealed interface->class,
> class,... pattern to model union types in general. Is it a good strategy or
> an antipattern that should be avoided?
>
> Great regards
> RedIODev
>
> On Fri, Jan 26, 2024, 12:42 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/dcd0aef7/attachment-0001.htm>


More information about the amber-dev mailing list