<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<tt><font size="+1">Let's assume that your trick works fine, Remi is
happy, and `default P` means that P is total, that the switch is
total, everything. Great. Now, what is the story for nested
patterns? <br>
<br>
  switch (container) {<br>
      case Box(Frog f): ...<br>
      case Box(Chocolate c): ...<br>
      case Box(var x): ....<br>
</font></tt><br>
<tt><font size="+1"><tt><font size="+1">Â Â Â Â Â Â case Bag(Frog f): ...<br>
      case Bag(Chocolate c): ...<br>
      case Bag(var x): ....<br>
<br>
   }<br>
<br>
We still have totality at the nested level; when container
is a box or a bag, the catch-all case is total on that kind
of container, but no one has said "default" or "total" or
anything like that. And a Box(null) will get dumped into
the third case. Do we care? <br>
<br>
I don't, really, but you knew that. Remi might, but we'll
have to hear from him. But I offer this example as a
bisection to determine whether the discomfort is really
about totality-therefore-nullable in patterns, or really
just about exhaustive switches (and the nullity thing is a
red herring.)<br>
<br>
So, who is bothered by the fact that case #3 gets Box(null),
and case #6 gets Bag(null)? Anyone? (And, if not, but you
are bothered by the lack of totality on the true catch-alls,
why not?)<br>
<br>
</font></tt></font></tt>
<div class="moz-cite-prefix">On 8/11/2020 6:37 PM, Guy Steele wrote:<br>
</div>
<blockquote type="cite"
cite="mid:C88674FB-205E-4821-9AE8-ED1FA1189CD4@oracle.com">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<br class="">
<div><br class="">
<blockquote type="cite" class="">
<div class="">On Aug 11, 2020, at 6:26 PM, Brian Goetz <<a
href="mailto:brian.goetz@oracle.com" class=""
moz-do-not-send="true">brian.goetz@oracle.com</a>>
wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<meta http-equiv="Content-Type" content="text/html;
charset=UTF-8" class="">
<div class=""> <br class="">
<blockquote type="cite"
cite="mid:16803318-455A-4F8A-A92B-9CBB0EBC406C@oracle.com"
class="">
<div class=""><span class="" style="font-family:
LucidaGrande; float: none; display: inline
!important;">On the other hand, I think Remi’s point
about totality being an implicit and non-local
property that is easily undermined by code changes
in another compilation unit is worrisome.</span></div>
</blockquote>
<br class="">
... which in turn derives from something else worrisome (a
problem we bought last year): that it is not clear from
looking at a switch whether it is exhaustive or not.Â
Expression switches must exhaustive, but statement
switches need not be. Here, we are saying that exhaustive
switch statements are a useful new thing (which they are)
and get rewarded with new behaviors (some may not find it
a reward), but you have to look too closely to determine
whether the switch is total. If it is, the last clause is
total too (well, unless it is an enum switch that names
all the constants, or a switch over a sealed type that
names all the sub-types but without a catch-all.)Â <br
class="">
<br class="">
So I claim that, if there is a problem, it is that it
should be more obvious that a switch is exhaustive on its
target. <br class="">
<br class="">
<blockquote type="cite"
cite="mid:16803318-455A-4F8A-A92B-9CBB0EBC406C@oracle.com"
class=""><font class="" face="LucidaGrande">Putting this
all together, I reach two conclusions:</font>
<div class=""><font class="" face="LucidaGrande"><br
class="">
</font></div>
<div class=""><font class="" face="LucidaGrande">(1) We
can live with the current definition of instanceof,
provided we make it clear that instanceof is not
purely equivalent to pattern matching, and that
instanceof and pattern matching can be simply
defined in terms of each other.</font></div>
</blockquote>
<br class="">
<font class="" face="LucidaGrande">I think we can do
slightly better than this. I argue that<br class="">
<br class="">
   x instanceof null<br class="">
<br class="">
is silly because we can just say<br class="">
<br class="">
   x == null<br class="">
<br class="">
instead (which is more direct), and similarly <br
class="">
<br class="">
   x instanceof var y<br class="">
   x instance of Object o<br class="">
<br class="">
are silly because we can just say<br class="">
<br class="">
   var y = x<br class="">
<br class="">
instead (again more direct). So let's just ban the
nullable patterns in instanceof, and no one will ever
notice. <br class="">
<br class="">
</font>
<blockquote type="cite"
cite="mid:16803318-455A-4F8A-A92B-9CBB0EBC406C@oracle.com"
class="">
<div class=""><font class="" face="LucidaGrande">(2) We
have a real disagreement about switch, but I think
the fault lies in the design of switch rather than
with pattern matching, and the fault is this:</font></div>
<div class=""><font class="" face="LucidaGrande"><br
class="">
</font></div>
<div class=""><font class="" face="LucidaGrande">Sometimes
when we write</font></div>
<div class=""><font class="" face="LucidaGrande"><br
class="">
</font></div>
<div class="">
<div class=""><span class="" style="font-family:
LucidaGrande; float: none; display: inline
!important;"><span class="Apple-tab-span" style="white-space:pre"> </span>switch
(v) {</span><br class="" style="font-family:
LucidaGrande;">
<span class="" style="font-family: LucidaGrande;
float: none; display: inline !important;"><span class="Apple-tab-span" style="white-space:pre"> </span>case
Type1 x: A</span><br class="" style="font-family:
LucidaGrande;">
<span class="" style="font-family: LucidaGrande;
float: none; display: inline !important;"><span class="Apple-tab-span" style="white-space:pre"> </span>case
Type2 y: B</span><br class="" style="font-family:
LucidaGrande;">
<span class="" style="font-family: LucidaGrande;
float: none; display: inline !important;"><span class="Apple-tab-span" style="white-space:pre"> </span>case
Type3 z: C</span><br class="" style="font-family:
LucidaGrande;">
</div>
</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div class=""><font class="" face="LucidaGrande"><br
class="">
</font></div>
<div class=""><font class="" face="LucidaGrande">we mean
for Type1 and Type 2 and Type3 to be three disparate
and co-equal things—in which case it seems absurd
for any of them to match null; but other times we
mean for Type3 to be a catchall, in which case we do
want it to match null if nothing before it has. <br
class="">
</font></div>
</blockquote>
<br class="">
<font class="" face="LucidaGrande">Agreed. The
fundamental concern that Remi (and Stephen, over on
a-dev) have raised is that we can't tell which it is,
and that is disturbing. (I still think it won't matter
in reality, but I understand the concern.)Â The same
ambiguity happens with deconstruction patterns:<br
class="">
<br class="">
   case Type3(var x, var y, var z) t3: ...<br class="">
<br class="">
which we can think of as "enhanced" type patterns. <br
class="">
</font></div>
</div>
</blockquote>
<div><br class="">
</div>
Sure.</div>
<div><br class="">
<blockquote type="cite" class="">
<div class="">
<div class=""><font class="" face="LucidaGrande">
(encouraging that our mails crossed with mostly the same
observation and possible fix.)Â <br class="">
<br class="">
</font>
<blockquote type="cite"
cite="mid:16803318-455A-4F8A-A92B-9CBB0EBC406C@oracle.com"
class=""><font class="" face="LucidaGrande">I believe
some previous discussion has focused on ways to modify
the _pattern_ to indicated either an expectation of
totality or a specific way of handling null. Â But at
this point I think augmenting patterns is overkill;
what we need (and all we need) is a modification to
the syntax of switch to indicate an expectation of
totality. Â I have a modest suggestion:</font>
<div class=""><font class="" face="LucidaGrande"><br
class="">
</font></div>
<div class="">
<div class=""><span class="" style="font-family:
LucidaGrande; float: none; display: inline
!important;"><span class="Apple-tab-span" style="white-space: pre;"> </span>switch
(v) {</span><br class="" style="font-family:
LucidaGrande;">
<span class="" style="font-family: LucidaGrande;
float: none; display: inline !important;"><span class="Apple-tab-span" style="white-space: pre;"> </span>case
Type1 x: A</span><br class="" style="font-family:
LucidaGrande;">
<span class="" style="font-family: LucidaGrande;
float: none; display: inline !important;"><span class="Apple-tab-span" style="white-space: pre;"> </span>case
Type2 y: B</span><br class="" style="font-family:
LucidaGrande;">
<span class="" style="font-family: LucidaGrande;
float: none; display: inline !important;"><span class="Apple-tab-span" style="white-space: pre;"> </span>case
Type3 z: C Â Â // Type3 is not expected to be a
catchall</span><br class="" style="font-family:
LucidaGrande;">
</div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>}</div>
</div>
<div class=""><br class="">
</div>
<div class="">
<div class=""><span class="" style="font-family:
LucidaGrande; float: none; display: inline
!important;"><span class="Apple-tab-span" style="white-space: pre;"> </span>switch
(v) {</span><br class="" style="font-family:
LucidaGrande;">
<span class="" style="font-family: LucidaGrande;
float: none; display: inline !important;"><span class="Apple-tab-span" style="white-space: pre;"> </span>case
Type1 x: A</span><br class="" style="font-family:
LucidaGrande;">
<span class="" style="font-family: LucidaGrande;
float: none; display: inline !important;"><span class="Apple-tab-span" style="white-space: pre;"> </span>case
Type2 y: B</span><br class="" style="font-family:
LucidaGrande;">
<span class="" style="font-family: LucidaGrande;
float: none; display: inline !important;"><span class="Apple-tab-span" style="white-space: pre;"> </span>default case
Type3 z: C Â Â // Type3 is expected to be a
catchall; it is a static error if Type3 is not
total on v,</span><br class="" style="font-family:
LucidaGrande;">
</div>
<div class=""><span class="" style="font-family:
LucidaGrande; float: none; display: inline
!important;"><span class="Apple-tab-span" style="white-space:pre"> </span>//
and Type3 will match null (unlike Type1 and Type2)</span></div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>}</div>
</div>
</blockquote>
<br class="">
And we already had another reason to want something like
this: expression switches are exhaustive, statement
switches are not, and we'd like to be able to engage the
compiler to do exhaustiveness checking for statement
switches even in the absence of patterns. <br class="">
<br class="">
<blockquote type="cite"
cite="mid:16803318-455A-4F8A-A92B-9CBB0EBC406C@oracle.com"
class="">
<div class="">Now, I will admit that this syntax is a
wee bit delicate, because adding a colon might
apparently change the meaning:</div>
<div class=""><br class="">
</div>
<div class=""><span class="" style="font-family:
LucidaGrande; float: none; display: inline
!important;"><span class="Apple-tab-span" style="white-space: pre;"> </span>switch
(v) {<br class="" style="font-family: LucidaGrande;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>case
Type1 x: A<br class="" style="font-family:
LucidaGrande;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>case
Type2 y: B<br class="" style="font-family:
LucidaGrande;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>default:
case Type3 z: C
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>}</div>
</span></div>
</blockquote>
<br class="">
Or `final case` or `finally <pattern>` or
`default-case` or ...<br class="">
<br class="">
I am iffy about `default` because of its historical
association, but I will have to re-think it in light of
this idea before I have an opinion. <br class="">
</div>
</div>
</blockquote>
<div><br class="">
</div>
I don;t care about the syntax very much.  I thought of “defaultâ€
because it sort of communicates the right idea and is already a
keyword: it says that the last clause is BOTH a case (with a
pattern) but also a catchall.</div>
<div><br class="">
</div>
<div>I have to admit that “default case†(there is really no need
for a hyphen here) is a bit wordy compared to “finallyâ€, which
is very clever but could cause some cognitive dissonance in
users who think too hard about “try†(really? a case clause that
is always executed before you exit the switch??).</div>
<div><br class="">
<blockquote type="cite" class="">
<div class="">
<div class="">
<blockquote type="cite"
cite="mid:16803318-455A-4F8A-A92B-9CBB0EBC406C@oracle.com"
class="">
<div class=""><span class="" style="font-family:
LucidaGrande; float: none; display: inline
!important;">
<div class="">but I believe that in situations that
matter, the compiler can and will reject this last
example on other grounds (please correct me if I
am mistaken</div>
</span></div>
</blockquote>
<br class="">
yes, the compiler can catch this.<br class="">
<br class="">
The other degree of freedom on this mini-feature is
whether `default` is a hint, or whether it would be an
error to not say `default` on a total pattern. I think it
might be seen as a burden if it were required, but Remi
might think it not strong enough if its just a hint. <br
class="">
</div>
</div>
</blockquote>
<br class="">
</div>
<div>Yeah, I thought about that, and decided that it would be a
bad idea for the compiler to complain about the absence of
“defaultâ€, in part because you don't want to feel vaguely
obligated to include it in simple cases involving, for example,
exhaustive use of enums.</div>
<div><br class="">
</div>
<div><br class="">
</div>
<br class="">
</blockquote>
<br>
</body>
</html>