<div dir="ltr"><br><div style="font-family:monospace" class="gmail_default">Heh, we're both unpaid :P I tutor folks from my university and church, as well as a couple of friends and family. Slowing down now though because of workload at work.<br><br>But back to the point.<br><br>> I think the problem is that without static "global"<br>> fields are always accessible and all the nested classes<br>> in their program are instansable from anywhere.<br>><br>> Once you have a static method, a method on a record, a<br>> method on an enum, or a static inner class this is no<br>> longer the case.<br><br>Apologies, maybe I missed the memo. I have been out of touch with this (and all other JEP's) because of my insane workload for the past couple of months.<br><br>Why would adding a static method change any of the logic?<br><br>I took your example in Java 22, added a static method, and everything worked dandy.<br><br>Am I missing something?</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Jun 1, 2024 at 9:28 PM Ethan McCue <<a href="mailto:ethan@mccue.dev">ethan@mccue.dev</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="auto"><div>I am also basically just a tutor, just unpaid.<div dir="auto"><br></div><div dir="auto">I think the problem is that without static "global" fields are always accessible and all the nested classes in their program are instansable from anywhere.</div><div dir="auto"><br></div><div dir="auto">Once you have a static method, a method on a record, a method on an enum, or a static inner class this is no longer the case.</div><div dir="auto"><br></div><div dir="auto">Trite example of the mechanics I'm referencing:</div><div dir="auto"><br></div><div dir="auto">int count = 0;</div><div dir="auto"><br></div><div dir="auto">class A {</div><div dir="auto"> void b() {</div><div dir="auto"> count++;</div><div dir="auto"> c();</div><div dir="auto"> new D();</div><div dir="auto"> }</div><div dir="auto">}</div><div dir="auto"><br></div><div dir="auto">void c() {</div><div dir="auto"> println("" + count);</div><div dir="auto">}</div><div dir="auto"><br></div><div dir="auto">class D {}</div><div dir="auto"><br></div><div dir="auto">void main() {</div><div dir="auto"> new A().b();</div><div dir="auto">}</div><div dir="auto"><br></div>So when you show static methods, I think you need to understand why count++; and c(); and new D(); would not function.</div><div dir="auto"><br></div><div dir="auto">That requires knowing that you are actually in an anonymous class. That requires we get past import static <a href="http://java.io.IO" target="_blank">java.io.IO</a>. That's the loop.</div><div dir="auto"><br></div><div dir="auto"><br><br><div class="gmail_quote" dir="auto"><div dir="ltr" class="gmail_attr">On Sat, Jun 1, 2024, 8:59 PM David Alayachew <<a href="mailto:davidalayachew@gmail.com" target="_blank">davidalayachew@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"><div><span class="gmail_default" style="font-family:monospace">Maybe I am missing something, but a static import seems like the natural next step to teaching a student who made it that far.</span></div><div><span class="gmail_default" style="font-family:monospace"><br></span></div><div><span class="gmail_default" style="font-family:monospace">If a student feels the need to break out of the bounds of an implicitly declared class, they must first understand what a class is going to save them from. In this case, it is allowing code they right to be reused else where.</span></div><div><span class="gmail_default" style="font-family:monospace"><br></span></div><div><span class="gmail_default" style="font-family:monospace">I am only a tutor, not a full-blown teacher, but when tutoring folks in this exact subject, I would always start by taking one of their projects, ask them to tweak in a subtle, but difficult way, then let them run headfirst into the problem. Once they start to feel the strain, I would introduce them to the concepts of classes.</span></div><div><span class="gmail_default" style="font-family:monospace"><br></span></div><div><span class="gmail_default" style="font-family:monospace">I would start by showing them how to create a simple pure function, similar to java.lang.Math. From there, we would make a few pure functions that are unrelated to their current task, and then have them get comfortable with that concept.</span></div><div><span class="gmail_default" style="font-family:monospace"><br></span></div><div><span class="gmail_default" style="font-family:monospace">Then, we would make another pure function that is being done repeatedly in their "JumboClass1" and "JumboClass2", and then have them get comfortable using this helper method in both versions.</span></div><div><span class="gmail_default" style="font-family:monospace"><br></span></div><div><span class="gmail_default" style="font-family:monospace">In my mind, this is naturally where the student would discover that they need to do a static import. In which case, they are in the middle of understanding a class, they understand imports, and they understand static methods fairly well. So, a static import has been well prepared for them.</span></div><div><span class="gmail_default" style="font-family:monospace"><br></span></div><div><span class="gmail_default" style="font-family:monospace">For me, this is a neat and clean introduction. Maybe I am missing something?<br></span></div><div><span class="gmail_default" style="font-family:monospace"></span></div><div><span class="gmail_default" style="font-family:monospace"></span></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Jun 1, 2024 at 6:43 PM Ron Pressler <<a href="mailto:ron.pressler@oracle.com" rel="noreferrer" target="_blank">ron.pressler@oracle.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">Hi.<br>
<br>
Without getting into the merits of not implicitly importing anything, let me just point out that the following is a valid program under the current JEP:<br>
<br>
void main() {<br>
IO.println(“Hello, world!”);<br>
}<br>
<br>
As is this one:<br>
<br>
import module java.base;<br>
<br>
void main() {<br>
IO.println(“Hello, world!”);<br>
}<br>
<br>
In other words, the fact that there are implicit imports doesn’t mean that you can’t ignore them or add them explicitly. if you find teaching this to be easier, you can. So even if you don’t find implicit imports helpful, they may be helpful to other teachers, who may not want to start with some import incantation that necessarily implies some programming-in-the-large concept.<br>
<br>
But I think that your unease mostly stems from the extra magic that implicit classes enjoy, and which isn’t strictly necessitated by their primary quality of being implicitly declared classes, and that extra magic differentiates them from regular compilation units along some other axis; is that right?<br>
<br>
— Ron<br>
<br>
<br>
<br>
> On 1 Jun 2024, at 23:14, Ethan McCue <<a href="mailto:ethan.mccue@lumanu.com" rel="noreferrer" target="_blank">ethan.mccue@lumanu.com</a>> wrote:<br>
> <br>
> Hi all,<br>
> <br>
> I'm following the development of JEP 477[1] and I feel the need to question the impetus for the implicit static imports.<br>
> <br>
> As of now[2] any program like this<br>
> <br>
> void main() {<br>
> println("Hello, world");<br>
> }<br>
> <br>
> Is equivalent to<br>
> <br>
> import static java.io.IO.print;<br>
> import static java.io.IO.println;<br>
> import static java.io.IO.writeln;<br>
> <br>
> import module java.base;<br>
> <br>
> final class Main {<br>
> void main() {<br>
> println("Hello, world");<br>
> }<br>
> }<br>
> <br>
> Where all the methods in <a href="http://java.io.IO" rel="noreferrer noreferrer" target="_blank">java.io.IO</a> delegate to newly added equivalent methods in java.io.Console.[3]<br>
> <br>
> Aside from muddying that API up (now there is readln and readLine + println and printLine which...what) I'm still concerned on how those implicit imports will affect the transition to named classes.<br>
> <br>
> Assume we start a student out here<br>
> <br>
> void main() {<br>
> println("Hello, world");<br>
> }<br>
> <br>
> You can get through conditionals, loops, variables, methods, and return types before touching classes or access specifiers.<br>
> <br>
> int compute() {<br>
> int total = 0;<br>
> for (int i = 0; i < 10; i++) {<br>
> total += i;<br>
> }<br>
> return total;<br>
> }<br>
> <br>
> void main() {<br>
> println("Hello: " + compute());<br>
> }<br>
> <br>
> You can even talk about records and enums in a hand wavey way. Enums are "one of these options", Records are "if you want to return two things."<br>
> <br>
> enum Pirate {<br>
> BLACKBEARD,<br>
> OTHER<br>
> }<br>
> <br>
> record Pos(int x, int y) {}<br>
> <br>
> Pos treasure(Pirate pirate) {<br>
> switch (pirate) {<br>
> case BLACKBEARD -><br>
> return new Pos(5, 5);<br>
> case OTHER -><br>
> return new Pos(0, 0);<br>
> }<br>
> }<br>
> <br>
> void main() {<br>
> println(treasure(Pirate.OTHER));<br>
> }<br>
> <br>
> So it is reasonable for a student to have made a relatively complex program before having to get to that point, but I think you do need to explain what exactly is going on with the anonymous main class when you introduce multi file programs.<br>
> <br>
> As originally pitched, this transition would have just meant wrapping the whole program in class Main {}, but now to make the transition from<br>
> <br>
> void main() {<br>
> // Arbitrary code<br>
> }<br>
> <br>
> to <br>
> <br>
> class Main {<br>
> void main() {<br>
> // Arbitrary code<br>
> }<br>
> }<br>
> <br>
> In a robust way, you need to add those imports to the top. You can skip the final since the semantics of extension haven't been relevant yet.<br>
> <br>
> import static java.io.IO.*;<br>
> <br>
> import module java.base;<br>
> <br>
> class Main {<br>
> void main() {<br>
> // Arbitrary code<br>
> }<br>
> }<br>
> <br>
> My gripe is that the concepts introduced here - static, module, and * imports - would have had no place to be introduced earlier.<br>
> <br>
> If you have folks write static methods on inner classes, the metaphor of a "global field" that otherwise exists in the simple-main world goes away.<br>
> <br>
> // For every program up until this, they could freely access this from anywhere<br>
> int count = 0;<br>
> <br>
> // And they could freely make an instance of any inner class<br>
> class Other {}<br>
> <br>
> class Pos {<br>
> static Pos of(int x, int y) {<br>
> // So the rules they are used to don't apply anymore<br>
> // and the explanation as to why really lies *after* they understand<br>
> // what an anonymous main class is and does<br>
> // ...<br>
> }<br>
> }<br>
> <br>
> void main() {<br>
> // ... <br>
> }<br>
> <br>
> If you have folks *use* static methods that is fine - the hand-waving of Math.max doesn't seem to trip anyone up - but I can't figure out how to topologically sort topics such that import static makes any sense before going through multi-file programs. <br>
> <br>
> I have a similar concern with import module, but that can be hand waved as "gets you everything from this library" so I am less concerned. Still don't fully understand the desire to have it be implicit, but less concerned. <br>
> <br>
> Just as a hypothetical, say <a href="http://java.io.IO" rel="noreferrer noreferrer" target="_blank">java.io.IO</a> was <a href="http://java.lang.IO" rel="noreferrer noreferrer" target="_blank">java.lang.IO</a>. No new import rules needed and now IO is available to all programs.<br>
> <br>
> void main() {<br>
> IO.printLine("Hello, world");<br>
> }<br>
> <br>
> While this does introduce something not explained - static method access - it feels easier to hand-wave away than import static java.io.IO.*; would be. It calls the printLine method, it comes from IO. IO means "Input/Output". That's a workable metaphor and can be glanced over in the same way as Math.max<br>
> <br>
> The transition from here to classes can again be "it's the same as if you had class Main {} around it" instead of "it's the same as if you had class Main {} around it and these imports. A static import imports a static method. A static method is a method attached to the class itself instead of the instance.... etc."<br>
> <br>
> Also, IO. feels like a different kind of unexplained boilerplate than public static void main(String[] args) {}. There is a lot of ground you need to cover before access modifiers, static methods, or command line arguments make any sort of sense. When you have someone write IO they are in that moment producing output and will soon take input.<br>
> <br>
> What am I overlooking?<br>
> <br>
> <br>
> [1]: <a href="https://openjdk.org/jeps/477" rel="noreferrer noreferrer" target="_blank">https://openjdk.org/jeps/477</a><br>
> [2]: <a href="https://download.java.net/java/early_access/jdk23/docs/api/java.base/java/io/IO.html" rel="noreferrer noreferrer" target="_blank">https://download.java.net/java/early_access/jdk23/docs/api/java.base/java/io/IO.html</a><br>
> [3] <a href="https://download.java.net/java/early_access/jdk23/docs/api/java.base/java/io/Console.html#print(java.lang.Object)" rel="noreferrer noreferrer" target="_blank">https://download.java.net/java/early_access/jdk23/docs/api/java.base/java/io/Console.html#print(java.lang.Object)</a><br>
<br>
</blockquote></div>
</blockquote></div></div></div>
</blockquote></div>