<div dir="ltr">It would be good to fix what you are saying. However, I don't agree that this enhancement would introduce any new rule. Rule for final variables and fields is one and only one in this context: it must be initialized once. This fix would just make enforcement of this rule more precise by modifying existing compiler rules that currently don't let through code that is intuitively and factually correct, but falls into a blind spot of specifications. Of course, JLS defines a set of rules on how to determine whether the value was previously assigned or not, and, strictly speaking, current behaviour is the right one. However, JLS here fails to let through valid code from, lets say, a logical point of view. So, actually, no one introduces new rules to the compiler. In fact, this fix would remove exception from the rules that are semantically applied to final variables.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Jul 13, 2024 at 12:54 PM Attila Kelemen <<a href="mailto:attila.kelemen85@gmail.com">attila.kelemen85@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Thanks, it is good to see `Thread.stop` go (though as far as I can see it was only made dysfunctional in JDK 20).<div><br></div><div>That said, I think my main point still stands. It is a complicated rule to completely explain. A clear evidence to this is that Archie's original definition is certainly not what people would expect for this rule, because they would expect this to compile then:</div><div><br></div><div>```</div><div>final int x;<br>try {<br>  if (cond1) x = f1();<br>  else x = f2();<br>} catch (Exception e) {<br>  x = f3();<br>}<br></div><div>```</div><div><br></div><div>where the last statement of the `try` block is not an assignment statement.</div><div><br></div><div>Also, my real concern here is that people are not pointing out where this is truly annoying. Because the reason you need that final so much because you want this to work:</div><div><br></div><div>```</div><div>final int x;<br>try {<br>  x = 4;<br>} catch (Exception e) {<br>  x = 2;<br>}<br><br>executor.execute(() -> System.out.println(x));<br></div><div>```</div><div><br></div><div>If so, then this "compiler fix" is a very special case, and not solving the true issue. Since it does not solve the following (which is equally annoying):</div><div><br></div><div>```</div><div>int x = 4;<br>if (something()) {<br>  x = 2;<br>}<br><br>executor.execute(() -> System.out.println(x));<br>// No more assignments to `x`<br></div><div>```</div><div><br></div><div>Even though this could be solved by naturally relaxing the constraint on captured local variables, and in that case not many people would complain about Archie's issue in my opinion/</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Tagir Valeev <<a href="mailto:amaembo@gmail.com" target="_blank">amaembo@gmail.com</a>> ezt írta (időpont: 2024. júl. 13., Szo, 7:02):<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">Hello!</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jul 12, 2024 at 10:44 PM Attila Kelemen <<a href="mailto:attila.kelemen85@gmail.com" target="_blank">attila.kelemen85@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">I personally wouldn't like too much if the compiler tried to be very smart with this. The current behavior is very easy to reason about, and this proposal looks too special to me. Especially because then it raises more questions about `Thread.stop`.</div></blockquote><div><br></div><div>Thread.stop is not an issue anymore, as it's dysfunctional since Java 18:</div><div><a href="https://bugs.openjdk.org/browse/JDK-8277861" target="_blank">https://bugs.openjdk.org/browse/JDK-8277861</a></div><div>It still could be possible to generate an exception in the thread using JVM TI though. On the other hand, you can update final local variable using JVM TI as well, so it should not be a problem.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div></div><div>Also, the way this issue is presented is not much of a concern (at least for the example code). Not making the local variable final is kinda whatever. Where this is annoying is when you want to capture the variable (mostly in a lambda). However, if that is the issue that you are trying to address, then I think this is the wrong solution to that issue. I think the real solution to the issue would be relaxing the constraint to be able to capture a local variable: We should be able to capture it, iff the variable is definitely assigned before capturing, and there is definitely no assignment after it.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Archie Cobbs <<a href="mailto:archie.cobbs@gmail.com" target="_blank">archie.cobbs@gmail.com</a>> ezt írta (időpont: 2024. júl. 12., P, 22:24):<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>I'd like to propose a very minor language improvement and would appreciate any feedback.<br></div><div><br></div><div>This is a true corner case, but I bet most developers have tripped over it a few times. It's easy to work around... but still... <br></div><div><br></div><div>Here's a simple example:</div><div><br></div><div><span style="font-family:monospace">    void describeMyThread(Thread thread) {<br>        final String description;<br>        try {<br>            description = '"' + thread.getName() + "'";<br>        } catch (NullPointerException e) {<br>            description = "null";<br>        }<br>        System.out.println("the thread is " + description);<br>    }</span><br></div><div><br></div><div>This doesn't compile:</div><div><br></div><div><span style="font-family:monospace">    DUTest.java:8: error: variable description might already have been assigned<br>                description = "(null)";<br>                ^</span><br></div><div><br></div><div>The error is a false positive: there is no way an exception can be thrown in the try block <i>after</i> <span style="font-family:monospace">description</span> is assigned, because <span style="font-family:monospace">description</span> being assigned is literally the last thing that occurs in the try block.</div><div><br></div><div>Developers intuitively know that <span style="font-family:monospace">description</span> will be DU at the start of the catch block, so the error feels surprising and makes the compiler seem less smart than it should be.<br></div><div><br></div><div>My proposal is to fix this by adding a "try/catch DU exception" to §16.2.15:</div><div><br></div><div style="margin-left:40px">V is definitely unassigned before a catch block iff all of the following are true:<br>    V is definitely unassigned after the try block <b>or the try block ends with an assignment expression statement V=b and V is definitely unassigned after b</b><br>    V is definitely unassigned before every return statement ...<br></div><div><br></div><div>A prototype compiler implementation is <a href="https://github.com/openjdk/jdk/compare/master...archiecobbs:jdk:TryCatchDUException" target="_blank">here</a>.</div><div><br></div><div>Thoughts?</div><div><br></div><div>-Archie<br></div><div> </div><div><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature">Archie L. Cobbs<br></div></div></div>
</blockquote></div>
</blockquote></div></div>
</blockquote></div>
</blockquote></div>