Pattern matching for java.util.Optional
Nathan Reynolds
numeralnathan at gmail.com
Fri Jan 26 16:17:05 UTC 2024
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/9bc42646/attachment.htm>
More information about the amber-dev
mailing list