<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Hi David,</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Would you please have an exact reproducible testcase and the exact error that is produced?</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Based on your e-mail, I tried:</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
---</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<span style="font-family:monospace" class="ContentPasted0"><span style="color:#000000;background-color:#ffffff" class="ContentPasted0">class Test {
</span><br class="ContentPasted0">
sealed interface SomeInterface {} <br class="ContentPasted0">
record First() implements SomeInterface {} <br class="ContentPasted0">
record Second() implements SomeInterface {} <br class="ContentPasted0">
<br class="ContentPasted0">
<br class="ContentPasted0">
private void exhaustiveSwitchWithFinalUninitialized() <br class="ContentPasted0">
{ <br class="ContentPasted0">
<br class="ContentPasted0">
final int numA; <br class="ContentPasted0">
final int numB; <br class="ContentPasted0">
<br class="ContentPasted0">
SomeInterface abc = new First(); <br class="ContentPasted0">
<br class="ContentPasted0">
switch (abc) //compiler error unless we uncomment the default <br class="ContentPasted0">
{ <br class="ContentPasted0">
<br class="ContentPasted0">
case First f -> <br class="ContentPasted0">
{ <br class="ContentPasted0">
<br class="ContentPasted0">
numA = 1; <br class="ContentPasted0">
numB = 0; <br class="ContentPasted0">
<br class="ContentPasted0">
} <br class="ContentPasted0">
<br class="ContentPasted0">
case Second s -> <br class="ContentPasted0">
{ <br class="ContentPasted0">
<br class="ContentPasted0">
numA = 0; <br class="ContentPasted0">
numB = 1; <br class="ContentPasted0">
<br class="ContentPasted0">
} <br class="ContentPasted0">
/* <br class="ContentPasted0">
default -> <br class="ContentPasted0">
{ <br class="ContentPasted0">
<br class="ContentPasted0">
numA = 2; <br class="ContentPasted0">
numB = 2; <br class="ContentPasted0">
<br class="ContentPasted0">
} <br class="ContentPasted0">
*/ <br class="ContentPasted0">
} <br class="ContentPasted0">
<br class="ContentPasted0">
System.out.println(numA + ""); <br class="ContentPasted0">
System.out.println(numB + ""); <br class="ContentPasted0">
<br class="ContentPasted0">
} <br class="ContentPasted0">
}<br class="ContentPasted0">
</span>---</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Which seems to build fine on a (custom build of) JDK <span style="font-family:monospace">
<span style="color:#000000;background-color:#ffffff" class="ContentPasted1">19b36 (jdk-19+36</span>)</span><span style="font-family: Calibri, Helvetica, sans-serif;">:</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<span style="font-family: Calibri, Helvetica, sans-serif;">---</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<span style="font-family:monospace"><span class="ContentPasted2"><span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); font-family: Calibri, Helvetica, sans-serif;" class="ContentPasted2">$ javac --enable-preview -source 19 /tmp/Test.java
</span><br class="ContentPasted2">
</span></span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<span style="font-family:monospace" class="elementToProof"><span class="ContentPasted2" style="font-family: Calibri, Helvetica, sans-serif;">Note: /tmp/Test.java uses preview features of Java SE 19.
</span><span class="ContentPasted2"><br class="ContentPasted2">
</span><span class="ContentPasted2" style="font-family: Calibri, Helvetica, sans-serif;">Note: Recompile with -Xlint:preview for details.</span><span class="ContentPasted2"><br class="ContentPasted2">
</span></span><span style="font-family: Calibri, Helvetica, sans-serif;" class="elementToProof">---</span><span style="font-family:monospace" class="elementToProof"><br>
</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<span style="font-family:monospace"><br>
</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<span style="font-family: Calibri, Helvetica, sans-serif;">I checked both the JLS and javac, at it seems that as long as the switch is exhaustive, the variables should be definitely assigned.</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<span style="font-family:monospace"><br>
</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<span style="font-family: Calibri, Helvetica, sans-serif;">Thanks,</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<span style="font-family: Calibri, Helvetica, sans-serif;"> Jan</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<span style="font-family:monospace"><br class="ContentPasted1">
</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> amber-dev <amber-dev-retn@openjdk.org> on behalf of David Alayachew <davidalayachew@gmail.com><br>
<b>Sent:</b> Saturday, October 8, 2022 4:34 PM<br>
<b>To:</b> Remi Forax <forax@univ-mlv.fr><br>
<b>Cc:</b> amber-dev <amber-dev@openjdk.org><br>
<b>Subject:</b> Re: Compiler could be smarter when dealing with exhaustive switch and final variables?</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div class="x_gmail_default" style="font-family:monospace">
<div class="x_gmail_default" style="font-family:monospace">
<div>
<div>Hello Rémi,</div>
<span class="x_gmail-im">
<div><br>
</div>
<div>First off, apologies for double sending - I sent to just you instead of to the mailing list too.<br>
</div>
<div><br>
</div>
<div>> Hi David,</div>
<div>> i think this is similar to</div>
<div>> <a href="https://bugs.openjdk.org/browse/JDK-8294670" target="_blank">https://bugs.openjdk.org/browse/JDK-8294670</a><br>
</div>
<div>> that i've reported recently.</div>
</span></div>
</div>
<div class="x_gmail_default" style="font-family:monospace">Whoops, apologies. I even see linked in the bug report that the issue was even reported on the same mailing list barely a week ago. I've been falling behind on reading the mailing lists. I'll be sure
to catch up before posting bug reports in the future.</div>
<span class="x_gmail-im">
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace">> You can even abuse of the switch + record pattern
<br>
</div>
<div class="x_gmail_default" style="font-family:monospace">> to extract numA and numB :)
<br>
</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
</span>
<div class="x_gmail_default" style="font-family:monospace">What a clever idea lol. Expressiveness be damned, but your solution actually works.</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace">I have been trying to use local records more frequently, but there's this one annoying edge case that has made me shy away from using them as much (<a href="https://bugs.openjdk.org/browse/JDK-8287885" target="_blank">https://bugs.openjdk.org/browse/JDK-8287885</a>).
But if there's flexibility like this to be found, then it sounds like I should lean more into local records.</div>
<span class="x_gmail-im">
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace">> BTW, this kind of code is less unreadable in languages like Scala where
<br>
</div>
<div class="x_gmail_default" style="font-family:monospace">> the switch is postfix to the value switched upon and not prefix.
<br>
</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
</span>
<div class="x_gmail_default" style="font-family:monospace">I'm still digesting the comment about type classes that you mentioned last time. Seems like Scala has a lot to teach me as a language.</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace">Thank you for your response and its insight!</div>
<font color="#888888">
<div class="x_gmail_default" style="font-family:monospace">David Alayachew</div>
</font></div>
</div>
<br>
<div class="x_gmail_quote">
<div dir="ltr" class="x_gmail_attr">On Sat, Oct 8, 2022 at 6:22 AM Remi Forax <<a href="mailto:forax@univ-mlv.fr">forax@univ-mlv.fr</a>> wrote:<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div>
<div style="font-family:arial,helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<div><br>
</div>
<div><br>
</div>
<hr id="x_m_-4995060696310533237zwchr">
<div>
<blockquote style="border-left:2px solid rgb(16,16,255); margin-left:5px; padding-left:5px; color:rgb(0,0,0); font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<b>From: </b>"David Alayachew" <<a href="mailto:davidalayachew@gmail.com" target="_blank">davidalayachew@gmail.com</a>><br>
<b>To: </b>"amber-dev" <<a href="mailto:amber-dev@openjdk.org" target="_blank">amber-dev@openjdk.org</a>><br>
<b>Sent: </b>Saturday, October 8, 2022 9:07:31 AM<br>
<b>Subject: </b>Compiler could be smarter when dealing with exhaustive switch and final variables?<br>
</blockquote>
</div>
<div>
<blockquote style="border-left:2px solid rgb(16,16,255); margin-left:5px; padding-left:5px; color:rgb(0,0,0); font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<div dir="ltr">
<div class="x_gmail_default" style="font-family:monospace">Hello Amber Dev Team,</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace">When if/else statements and final variables combine, the compiler can make some helpful assertions. Consider the following code.<br>
</div>
<div class="x_gmail_default" style="font-family:monospace"> <br>
sealed interface SomeInterface {}<br>
record First() implements SomeInterface {}<br>
record Second() implements SomeInterface {} <br>
<br>
private void exhaustiveIfWithFinalUninitialized()<br>
{<br>
<br>
SomeInterface abc = new First();<br>
<br>
final int numA;<br>
final int numB;<br>
<br>
if (abc instanceof First)<br>
{<br>
<br>
numA = -1;<br>
numB = -1;<br>
<br>
}<br>
<br>
else if (abc instanceof Second)<br>
{<br>
<br>
numA = -2;<br>
numB = -2;<br>
<br>
}<br>
<br>
else<br>
{<br>
<br>
throw new IllegalStateException("This shouldn't be possible!");<br>
<br>
}<br>
<br>
System.out.println(numA + "");<br>
System.out.println(numB + "");<br>
<br>
}</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace">The above code compiles with no errors whatsoever. The compiler is smart enough to realize that, no matter what, numA and numB will most certainly be populated by the time we reach the print statements
below the if statements. <br>
</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace">However, the compiler does not make the same realization when working with exhaustive switches. But since the switch statement is exhaustive, shouldn't the compiler be able to make the same realization
here? If anything, the switch should be capable of all of the above and more, correct?
<br>
</div>
<div class="x_gmail_default" style="font-family:monospace"> <br>
private void exhaustiveSwitchWithFinalUninitialized()<br>
{<br>
<br>
final int numA;<br>
final int numB;<br>
<br>
SomeInterface abc = new First();<br>
<br>
switch (abc) //compiler error unless we uncomment the default <br>
{<br>
<br>
case First f -><br>
{<br>
<br>
numA = 1;<br>
numB = 0;<br>
<br>
}<br>
<br>
case Second s -> <br>
{<br>
<br>
numA = 0;<br>
numB = 1;<br>
<br>
}<br>
/*<br>
default -><br>
{<br>
<br>
numA = 2;<br>
numB = 2;<br>
<br>
}<br>
*/<br>
}<br>
<br>
System.out.println(numA + "");<br>
System.out.println(numB + "");<br>
<br>
}</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace">I would like it if the compiler could make the same realizations it did for the if statement. I should also add, this seems to apply to all forms of exhaustive switch except for those with default clauses.</div>
</div>
</blockquote>
<div><br>
</div>
<div>
<div>Hi David,</div>
<div>i think this is similar to</div>
<div> <a href="https://bugs.openjdk.org/browse/JDK-8294670" target="_blank">https://bugs.openjdk.org/browse/JDK-8294670</a><br>
</div>
<div>that i've reported recently.</div>
</div>
<div><br>
</div>
<blockquote style="border-left:2px solid rgb(16,16,255); margin-left:5px; padding-left:5px; color:rgb(0,0,0); font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<div dir="ltr">
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace">Obviously, this is easy to work around - I could just make a switch expression for each variable, and then just populate them individually. Alternatively, I could just put a default clause any time
I need that compiler realization, though I give up some benefits from exhaustive switch as a result.<br>
</div>
</div>
</blockquote>
<div><br>
</div>
As a workaround, you can also group the values into a record (that can be local to the method) and use an expression switch and initialize the local variable after the switch.</div>
<div><br>
</div>
<div>You can even abuse of the switch + record pattern to extract numA and numB :)<br>
</div>
<div><br>
</div>
<div> record Pair(int numA, int numB) {}</div>
<div> switch(switch(abc) {
<div> case First -> new Pair(1, 0);<br>
case Second -> new Pair(0, 1);</div>
<div> }) {<br>
</div>
</div>
<div> case Pair(int numA, int numB) -> {<br>
</div>
<div> System.out.println(numA);<br>
</div>
<div> System.out.println(numB);<br>
</div>
<div> }<br>
</div>
<div> }</div>
<div>
<div><br>
</div>
<div>BTW, this kind of code is less unreadable in languages like Scala where the switch is postfix to the value switched upon and not prefix.<br>
</div>
<div><br>
</div>
<blockquote style="border-left:2px solid rgb(16,16,255); margin-left:5px; padding-left:5px; color:rgb(0,0,0); font-weight:normal; font-style:normal; text-decoration:none; font-family:Helvetica,Arial,sans-serif; font-size:12pt">
<div dir="ltr">
<div class="x_gmail_default" style="font-family:monospace">Thank you all for your time and help!</div>
<div class="x_gmail_default" style="font-family:monospace">David Alayachew</div>
</div>
</blockquote>
<div><br>
</div>
<div>regards,<br>
</div>
<div>Rémi<br>
</div>
<div><br>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</body>
</html>