<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<font size="4"><font face="monospace">Backing up, what you're saying
here is that both total and partial reference type patterns have
opinions about nullity (null-accepting and null-rejecting,
respectively), and while these may be reasonable defaults, you
would like to be able to "override" these defaults. I
sympathize.<br>
<br>
There was much discussion about whether we needed a separate way
of saying something like (T|Null), or T-but-not-null,
explicitly. As you can imagine, many syntaxes were proposed,
but they were all unsatisfying because (a) they ceded much
syntactic real estate (and therefore much mindshare) to a
distinction that was small, and often ignorable, and (b) if we
ever got nullity control in the future (T! and T?), these ad-hoc
pattern forms would look permanently silly. <br>
<br>
<br>
<br>
<br>
</font></font><br>
<div class="moz-cite-prefix">On 10/11/2023 7:25 PM, Steffen Yount
wrote:<br>
</div>
<blockquote type="cite" cite="mid:CAOBh0XBqWzW93wziHC5w42tHpoXK8=-T6OAfE0AEwLZwETcQ6g@mail.gmail.com">
<div dir="ltr">
<div>Amber devs,</div>
<div><br>
</div>
<div>For the Patterns available to us in Java 21 it has been
noted that:</div>
1) TypePatterns match unconditionally, that is to say they are
"null matching". Meanwhile RecordPatterns at most match
exhaustively leaving null valued ReferenceTypes in the
remainder, that is to say RecordPatterns are "non-null matching"
or "instance matching".<br>
<br>
2) It's the "null hostility" of the "switch" and "instanceof"
operators that prevents TypePatterns from matching/dominating
the null values there:<br>
<div><br>
</div>
<div>* In the case of "switch" a null valued ReferenceType
selector expression will cause a NullPointerException to be
thrown by the switch operator unless the "case null" switch
label has been declared in its switch block.</div>
<div><br>
</div>
<div>* In the case of "instanceof" evaluation, when the the
RelationalExpression is null valued, null is interpreted
semantically as "not an instance" and thus also as "not an
instance of" the ReferenceType (or Pattern) found to the right
of the "instanceof" keyword.</div>
<br>
<br>
This dichotomy between TypePatterns and RecordPatterns
illustrates a gap in current pattern matching coverage wherein
we cannot match null vs non-null vs nullable for non-record
ReferenceTypes.<br>
<br>
I would love to see this gap closed.<br>
<br>
<div>In JEP 455, I can see there's a lot of work going into
making Patterns work well with PrimitiveTypes, is anyone
looking into making Patterns work better with these
ReferenceTypes?<br>
</div>
<br>
What are your thoughts on closing this pattern matching coverage
gap and maybe implementing something like the following:<br>
<br>
The current Java 21 Pattern definitions look like<br>
<div><br>
<span style="font-family:monospace">Pattern:<br>
TypePattern<br>
RecordPattern</span><br>
<br>
The TypePattern part could be deconstructed and extended
giving new Pattern definitions that look more like:<br>
<br>
<span style="font-family:monospace">Pattern:<br>
PrimitivePattern (PrimitiveType)<br>
RecordPattern (non-null valued record ReferenceType)<br>
InstancePattern (non-null valued ReferenceType)<br>
NullPattern (null valued ReferenceType)<br>
ReferencePattern (ReferenceType)</span><br>
<br>
Notes:<br>
1) The InstancePattern matching a ReferenceType T and the
NullPattern matching that same ReferenceType T are complements
of each other and exhaustively cover the match space of a
ReferencePattern matching that same ReferenceType T<br>
<br>
2) The ReferencePattern matching a ReferenceType T dominates
both a NullPattern and a InstancePattern matching that same
ReferenceType T<br>
<br>
3) The RecordPattern matching a record ReferenceType T for a
Record declared with a zero-arg constructor exhaustively
covers the InstancePattern matching that same ReferenceType T<br>
<br>
4) The InstancePattern matching a record ReferenceType T
dominates a RecordPattern matching that same ReferenceType T<br>
<br>
Sample of proposed Pattern notation:<br>
<br>
<span style="font-family:monospace">match-only Pattern
notation:<br>
PrimitivePattern: int<br>
RecordPattern: Bat(_,_)<br>
InstancePattern: Bat()<br>
NullPattern: null<br>
ReferencePattern: Bat</span><br>
<br>
<span style="font-family:monospace">match+projection Pattern
notation: <br>
PrimitivePattern: int ii<br>
RecordPattern: Bat(_,_) bb<br>
InstancePattern: Bat() bb<br>
NullPattern: null bb<br>
ReferencePattern: Bat bb</span><br>
<br>
(When matched, the pattern's named variables are projected
into the appropriate declaration scope)<br>
<br>
Proposed Pattern appearance and idiomatic familiarity:<br>
PrimitivePattern: Resembles a local PrimitiveType variable
declaration<br>
RecordPattern: Resembles an "all-args" constructor call
for a record ReferenceType<br>
InstancePattern: Resembles a "no-args" constructor call
for a ReferenceType<br>
NullPattern: Resembles a ReferencePattern where the
ReferenceType has been replaced with the NullLiteral<br>
ReferencePattern: Resembles a local ReferenceType variable
declaration<br>
<br>
Does this notation feel good and Java-ish to you? Have you
already got something better figured out? Your thoughts?<br>
<br>
Thanks for your consideration,<br>
-Steffen</div>
</div>
</blockquote>
<br>
</body>
</html>