Do we really need an implicit "import static java.io.IO.*"?

David Alayachew davidalayachew at gmail.com
Sun Jun 2 22:29:34 UTC 2024


You may be right that we are delving into tangential waters.

I'll leave it at this -- I think this feature, as implemented, is perfectly
approachable for new students doing it my way. I see a smooth ramp all the
way up doing it the functional way. However, I do acknowledge that, if you
take a state based approach, then there is a non-trivial speed bump near
the halfway point.

As for whether or not to remove it and how, I leave to you all. But if we
were to remove it the way Ethan suggested, my strategy loses nothing. If
the change doesn't hurt me and helps him, then I have no problem with it.


On Sun, Jun 2, 2024 at 6:17 PM Olexandr Rotan <rotanolexandr842 at gmail.com>
wrote:

> Not sure if this conversation haven't shifted from its topic yet, but I
> would argue with the point that state is bad and you should prefer static
> methods wherever it is possible.
>
> There is a few layers to it. First and foremost, keeping some information
> in object state instead of passing it ap and down through long invocation
> chains is just simply better for readability. Extracting object is a most
> common refactoring to eliminate triads and higher order methods.
>
> Secondly, mutability isn't something inheritendly bad. What is bad is
> shared mutability. When mutations of state are encapsulated properly inside
> of the owning object, they aren't harmful at all. Moreover, properly
> dealing with state and mutability is one of the most important skills for
> developer. There is more to purity then just immutability, and furthermore,
> purity does not forbid mutability.
>
> Lastly, if students you are teaching would ever decide to become
> commercial developers, they would be inevitably struck with a fact that
> static methods here are almost considered antipattern and discarded in
> favor of singletone.
>
> So, to conclude, it is not about how far you can go without state, it is
> about how far you should go. Not even mentioning the fact that static
> methods provide no guarantee of purity, and instance methods do not imply
> impurity. Functional style now is so exaggerated people often forget why
> oop took over the world in the first place
>
> On Mon, Jun 3, 2024, 00:06 David Alayachew <davidalayachew at gmail.com>
> wrote:
>
>> Sometimes, I don't get the choice to avoid state. But when the
>> opportunity arises/the assignment doesn't require it, I will even encourage
>> the student to undo some work TO AVOID using state.
>>
>> So no, if I get the chance, I avoid it every chance I get.
>>
>> As for static methods, I don't usually get to choose for them. The choice
>> has usually been made, and there's a cost to undoing too much of their work.
>>
>> That said, most of what we work with is instance methods with as little
>> state as possible.
>>
>> But to be clear, the most interaction they have with INSTANCES is calling
>> it in their main method. Again, the goal is to get them using functional
>> for as long as possible.
>>
>> Sad to see dev.java on the list, but I have to agree with you. Never
>> considered it to be a beginner resource though.
>>
>> And as for being forced to eventually introduce state, you'd be shocked
>> just how far we can go with it lol. I can usually get them to GUI's before
>> I get forced into it. And even then, I don't let them introduce any state
>> of their own, just modifying a JFrame and stuff along that order, which is
>> incredibly easy to maintain for the kids.
>>
>> On Sun, Jun 2, 2024 at 3:36 PM Ethan McCue <ethan at mccue.dev> wrote:
>>
>>> I'm pondering a bit so this isn't too deep of a response
>>>
>>> > Their JumboClassA is very big and unwieldy, and they want to use parts
>>> of it for JumboClassB, and maybe other things I've introduced them to at
>>> that point. If I haven't already, I introduce them to the Math class, show
>>> them how it works, let them make a HelloWorld that does something
>>> meaningless, let them call it in their existing class, let them call it in
>>> another project, let them make a Math2, and then from there, they usually
>>> feel comfortable enough to try and extract a method from what they were
>>> actually doing into a pure, static function.
>>>
>>> Are you saying that you only have them write static methods to start
>>> with? Like
>>>
>>> class JumboClassA {
>>>     static int code() {
>>>         return JumboClassB.compute() + 1;
>>>     }
>>> }
>>>
>>> class JumboClassB {
>>>     static int compute() {
>>>         return 0;
>>>     }
>>> }
>>>
>>> If so, do you oft get around to instances and instance state?
>>>
>>> > Long story short, you and I approach tutoring in WILDLY different ways.
>>>
>>> Also in different contexts. I spend most of my time in one of a few
>>> discord channels answering questions and that sometimes leads to people who
>>> I tutor over a longer period of time. We mostly get people who are either
>>> struggling with an existing curriculum and try to do course correction (I
>>> started making a shortlist of the bad college curriculums we are exposed
>>> to).
>>>
>>> So the things we notice are that current curriculums either
>>> * Have ordering issues within them. Explaining JPA before SQL, Abstract
>>> classes before interfaces, Large program design before small, etc.
>>> * Have no clear next steps. Most intro courses, after taking a deep sigh
>>> of relief for having gotten a successful for loop out of a teenager, just
>>> sorta end.
>>>
>>> So we have very few Java courses (that we know of) to point people to
>>> that actually explain the topics they introduce in the order they will be
>>> encountered. (See https://dev.java/learn/ ,
>>> https://www.baeldung.com/java-tutorial,
>>> https://www.geeksforgeeks.org/java/ for examples of terrible tutorials)
>>>
>>> And after we give them something like https://java-programming.mooc.fi/
>>> and they finish we have nowhere to go from there. That's part of why I
>>> think topic order matters so much.
>>>
>>> > I have only tutored one student using this implicit class feature so
>>> far, and we are nowhere near this point yet.
>>>
>>> Take notes on how that progresses + any differences from your previous
>>> approach.
>>>
>>> > I guess what I am saying is that, since I don't really depend on
>>> static or instance level state, I just don't have this problem. And by the
>>> time I do, they have gotten so used to doing functional, that any
>>> interaction with global state stands out as something to watch out for.
>>>
>>> I went to Northeastern and their intro curriculum starts you with Racket
>>> doing really rigid comments that drills in sum types + recursion. Then they
>>> introduce Java without mutation at all for 80% of the 2nd semester. You
>>> only get mutation at the end and at that point your brain was broken from
>>> all the purity you forget how.
>>>
>>> So I get it. But eventually those concepts need to be introduced.
>>>
>>>
>>> On Sun, Jun 2, 2024 at 12:06 AM David Alayachew <
>>> davidalayachew at gmail.com> wrote:
>>>
>>>> Well, I definitely see the discrepancy now. Yes, this makes a lot of
>>>> sense.
>>>>
>>>> Apologies for not recognizing your point earlier, I had assumed that
>>>> you were talking about some fundamental execution change that the kid needs
>>>> to be aware of. I didn't realize that you were talking about potholes that
>>>> the kid might fall into.
>>>>
>>>> Long story short, you and I approach tutoring in WILDLY different ways.
>>>>
>>>> First and foremost, the concept of introducing instance state this
>>>> early on is dangerous in my eyes. If you have a kid that can dance at that
>>>> tempo, then you truly have a gifted kid. But from my 10+ years of tutoring,
>>>> EVERY SINGLE TIME I try to introduce them to the idea of having state
>>>> ANYWHERE except for inside of a method, things fall apart. It will be a
>>>> long time before I ever try and get this kid to try and manage state at the
>>>> instance level.
>>>>
>>>> I approach it very differently.
>>>>
>>>> I start off teaching these kids to approach problems with a functional
>>>> mindset. Pure functions everywhere. This usually ends up creating a big,
>>>> singular essay of a function, and once they start to feel the strain from
>>>> that, I show them how to thread their state in through methods and return
>>>> values.
>>>>
>>>> Anyways, back to my example from 2 emails ago.
>>>>
>>>> Their JumboClassA is very big and unwieldy, and they want to use parts
>>>> of it for JumboClassB, and maybe other things I've introduced them to at
>>>> that point. If I haven't already, I introduce them to the Math class, show
>>>> them how it works, let them make a HelloWorld that does something
>>>> meaningless, let them call it in their existing class, let them call it in
>>>> another project, let them make a Math2, and then from there, they usually
>>>> feel comfortable enough to try and extract a method from what they were
>>>> actually doing into a pure, static function.
>>>>
>>>> I have only tutored one student using this implicit class feature so
>>>> far, and we are nowhere near this point yet. But I expect that the only
>>>> thing that will change before I get there is explaining to them how, in
>>>> order to use their methods outside of the class, they need to give the
>>>> class an explicit name. I foresee no pain points with that. After all, how
>>>> can you reference a class that does not have an explicit name? And I expect
>>>> them to understand the unidirectionality of that. A class without a name
>>>> can use methods from a class WITH a name. But the reverse is false. I'm
>>>> actually sorted of excited to spring that onto the kids and see how they
>>>> react lol.
>>>>
>>>> Really, the only issue I ever run into is when kids ask me, what is
>>>> static useful for anyways? They usually feel like they only need static or
>>>> instance methods.
>>>>
>>>> I guess what I am saying is that, since I don't really depend on static
>>>> or instance level state, I just don't have this problem. And by the time I
>>>> do, they have gotten so used to doing functional, that any interaction with
>>>> global state stands out as something to watch out for. From there, they
>>>> understand how much of an ordeal it is to work with state, and exactly how
>>>> dangerous and error-prone that it is that I can usually get them to turn
>>>> their alertness up to 11 whenever the need arises.
>>>>
>>>> Let me first get your perspective though before I continue my point.
>>>> What are your thoughts on this?
>>>>
>>>> And apologies for not responding to your points individually. Our
>>>> assumptions are on opposite ends, so there is very little that I can
>>>> directly respond to.
>>>>
>>>> On Sat, Jun 1, 2024 at 11:22 PM Ethan McCue <ethan at mccue.dev> wrote:
>>>>
>>>>> I really should find a better example / adapt something in an existing
>>>>> curriculum - but:
>>>>>
>>>>> Mutation 1: Make b static
>>>>>
>>>>> int count = 0;
>>>>>
>>>>> class A {
>>>>>     static void b() {
>>>>>          count++;
>>>>>          c();
>>>>>          new D();
>>>>>     }
>>>>> }
>>>>>
>>>>> void c() {
>>>>>     println("" + count);
>>>>> }
>>>>>
>>>>> class D {}
>>>>>
>>>>> void main() {
>>>>>     new A().b();
>>>>> }
>>>>>
>>>>>
>>>>> https://run.mccue.dev/?runtime=latest&release=22&preview=enabled&gist=be416fe8e6df84c81c0f5526f0e28aef
>>>>>
>>>>> Mutation 2: Make c static
>>>>>
>>>>> int count = 0;
>>>>>
>>>>> class A {
>>>>>     void b() {
>>>>>          count++;
>>>>>          c();
>>>>>          new D();
>>>>>     }
>>>>> }
>>>>>
>>>>> static void c() {
>>>>>     println("" + count);
>>>>> }
>>>>>
>>>>> class D {}
>>>>>
>>>>> void main() {
>>>>>     new A().b();
>>>>> }
>>>>>
>>>>>
>>>>> https://run.mccue.dev/?runtime=latest&release=22&preview=enabled&gist=b71e9b94cff6099afb5153abffdbc3e9
>>>>>
>>>>> Mutation 3: (for fun) Make A a record
>>>>>
>>>>> int count = 0;
>>>>>
>>>>> record A() {
>>>>>     void b() {
>>>>>          count++;
>>>>>          c();
>>>>>          new D();
>>>>>     }
>>>>> }
>>>>>
>>>>> void c() {
>>>>>     println("" + count);
>>>>> }
>>>>>
>>>>> class D {}
>>>>>
>>>>> void main() {
>>>>>     new A().b();
>>>>> }
>>>>>
>>>>>
>>>>> https://run.mccue.dev/?runtime=latest&release=22&preview=enabled&gist=cb5bf4664bf83ffc8ee4e5fe85abadb6
>>>>>
>>>>> Maybe it's just a failure of imagination, but I don't know how to
>>>>> introduce static methods and fields into someone's arsenal without
>>>>> either
>>>>> * pulling the veil and explaining the anonymous class. This requires
>>>>> static imports. We've looped.
>>>>> * leaving them with guidance like "you can't make classes, records
>>>>> work though. I'll tell you later why. Just do math type stuff here."
>>>>>
>>>>> Then there is the confounding factor of *why* they would want a static
>>>>> method. In "real code" we use static methods and fields for
>>>>>
>>>>> * globals
>>>>> * "pure" logic
>>>>> * factory methods
>>>>>
>>>>> Before they move to another file, they already have globals and they
>>>>> can already put pure logic at the top level. Factory methods only make
>>>>> sense once you've introduced large program topics like visibility.
>>>>>
>>>>> I.E. you only need factory methods if
>>>>>
>>>>> 1. You want to hide a constructor
>>>>>
>>>>> class Point {
>>>>>     private Point(int x, int y) {}
>>>>>
>>>>>     static Point of(int x, int y) {
>>>>>         return new Point(x, y);
>>>>>     }
>>>>> }
>>>>>
>>>>> But this is a nuanced api topic and isn't even relevant when
>>>>> everything is a nestmate. Really a "large program" sort of choice.
>>>>>
>>>>> 2. You want to create through an interface
>>>>>
>>>>> interface LinkedList {
>>>>>     int size();
>>>>>
>>>>>     static LinkedList empty() {
>>>>>         return new EmptyList();
>>>>>     }
>>>>>
>>>>>     static LinkedList notEmpty(int head, LinkedList tail) {
>>>>>
>>>>>     }
>>>>> }
>>>>>
>>>>> class EmptyList implements LinkedList {
>>>>>     @Override
>>>>>     public int size() {
>>>>>        return 0;
>>>>>     }
>>>>> }
>>>>>
>>>>> But as you see from the code you need to have public to teach
>>>>> interfaces. You can gloss over it (my school did) but it's there. Even then
>>>>> "why not just new EmptyList()" has an answer really rooted in (again) large
>>>>> program concerns. You make code for potentially an external audience and
>>>>> need to give a "good" API.
>>>>>
>>>>> 3. You want otherwise incompatible overloads
>>>>>
>>>>> class Point {
>>>>>     Point(int x, int y) {}
>>>>>
>>>>>     static Point ofX(int x) {
>>>>>         return new Point(x, 0);
>>>>>     }
>>>>>
>>>>>     static Point ofY(int y) {
>>>>>         return new Point(0, y);
>>>>>     }
>>>>> }
>>>>>
>>>>> Which does work a little. But it doesn't really give a good opener for
>>>>> static imports. The method names you'd give here are like ofX, fromX. You
>>>>> would want to use those qualified every time. You also activate the
>>>>> footguns I showed above.
>>>>>
>>>>> int pointsMade = 0;
>>>>>
>>>>> class Point {
>>>>>     Point(int x, int y) {}
>>>>>
>>>>>     static Point ofX(int x) {
>>>>>         pointsMade++;
>>>>>         return new Point(x, 0);
>>>>>     }
>>>>>
>>>>>     static Point ofY(int y) {
>>>>>         pointsMade++;
>>>>>         return new Point(0, y);
>>>>>     }
>>>>> }
>>>>>
>>>>> --
>>>>>
>>>>> > 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.
>>>>>
>>>>> I think this is what I am missing. Without going into large or
>>>>> multi-file program design there isn't much reason to use static anything. *In
>>>>> addition* to that there are mechanical difficulties that can only be
>>>>> explained properly once you reach a 2nd file.
>>>>>
>>>>> I.E. - "you were actually using a class until now. For true globals
>>>>> use static fields", "For methods you can call anywhere use static" are the
>>>>> explanations I want to give. Both of those explanations need multiple files
>>>>> already in place to make sense.
>>>>>
>>>>> Does that track?
>>>>>
>>>>>
>>>>>
>>>>> On Sat, Jun 1, 2024 at 10:47 PM David Alayachew <
>>>>> davidalayachew at gmail.com> wrote:
>>>>>
>>>>>>
>>>>>> 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.
>>>>>>
>>>>>> But back to the point.
>>>>>>
>>>>>> > 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.
>>>>>> >
>>>>>> > 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.
>>>>>>
>>>>>> 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.
>>>>>>
>>>>>> Why would adding a static method change any of the logic?
>>>>>>
>>>>>> I took your example in Java 22, added a static method, and everything
>>>>>> worked dandy.
>>>>>>
>>>>>> Am I missing something?
>>>>>>
>>>>>> On Sat, Jun 1, 2024 at 9:28 PM Ethan McCue <ethan at mccue.dev> wrote:
>>>>>>
>>>>>>> I am also basically just a tutor, just unpaid.
>>>>>>>
>>>>>>> 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.
>>>>>>>
>>>>>>> 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.
>>>>>>>
>>>>>>> Trite example of the mechanics I'm referencing:
>>>>>>>
>>>>>>> int count = 0;
>>>>>>>
>>>>>>> class A {
>>>>>>>     void b() {
>>>>>>>          count++;
>>>>>>>          c();
>>>>>>>          new D();
>>>>>>>     }
>>>>>>> }
>>>>>>>
>>>>>>> void c() {
>>>>>>>     println("" + count);
>>>>>>> }
>>>>>>>
>>>>>>> class D {}
>>>>>>>
>>>>>>> void main() {
>>>>>>>     new A().b();
>>>>>>> }
>>>>>>>
>>>>>>> So when you show static methods, I think you need to understand why
>>>>>>> count++; and c(); and new D(); would not function.
>>>>>>>
>>>>>>> That requires knowing that you are actually in an anonymous class.
>>>>>>> That requires we get past import static java.io.IO. That's the loop.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Sat, Jun 1, 2024, 8:59 PM David Alayachew <
>>>>>>> davidalayachew at gmail.com> wrote:
>>>>>>>
>>>>>>>> Maybe I am missing something, but a static import seems like the
>>>>>>>> natural next step to teaching a student who made it that far.
>>>>>>>>
>>>>>>>> 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.
>>>>>>>>
>>>>>>>> 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.
>>>>>>>>
>>>>>>>> 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.
>>>>>>>>
>>>>>>>> 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.
>>>>>>>>
>>>>>>>> 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.
>>>>>>>>
>>>>>>>> For me, this is a neat and clean introduction. Maybe I am missing
>>>>>>>> something?
>>>>>>>>
>>>>>>>> On Sat, Jun 1, 2024 at 6:43 PM Ron Pressler <
>>>>>>>> ron.pressler at oracle.com> wrote:
>>>>>>>>
>>>>>>>>> Hi.
>>>>>>>>>
>>>>>>>>> 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:
>>>>>>>>>
>>>>>>>>>     void main() {
>>>>>>>>>         IO.println(“Hello, world!”);
>>>>>>>>>     }
>>>>>>>>>
>>>>>>>>> As is this one:
>>>>>>>>>
>>>>>>>>>     import module java.base;
>>>>>>>>>
>>>>>>>>>     void main() {
>>>>>>>>>         IO.println(“Hello, world!”);
>>>>>>>>>     }
>>>>>>>>>
>>>>>>>>> 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.
>>>>>>>>>
>>>>>>>>> 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?
>>>>>>>>>
>>>>>>>>> — Ron
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> > On 1 Jun 2024, at 23:14, Ethan McCue <ethan.mccue at lumanu.com>
>>>>>>>>> wrote:
>>>>>>>>> >
>>>>>>>>> > Hi all,
>>>>>>>>> >
>>>>>>>>> > I'm following the development of JEP 477[1] and I feel the need
>>>>>>>>> to question the impetus for the implicit static imports.
>>>>>>>>> >
>>>>>>>>> > As of now[2] any program like this
>>>>>>>>> >
>>>>>>>>> > void main() {
>>>>>>>>> >     println("Hello, world");
>>>>>>>>> > }
>>>>>>>>> >
>>>>>>>>> > Is equivalent to
>>>>>>>>> >
>>>>>>>>> > import static java.io.IO.print;
>>>>>>>>> > import static java.io.IO.println;
>>>>>>>>> > import static java.io.IO.writeln;
>>>>>>>>> >
>>>>>>>>> > import module java.base;
>>>>>>>>> >
>>>>>>>>> > final class Main {
>>>>>>>>> >     void main() {
>>>>>>>>> >         println("Hello, world");
>>>>>>>>> >     }
>>>>>>>>> > }
>>>>>>>>> >
>>>>>>>>> > Where all the methods in java.io.IO delegate to newly added
>>>>>>>>> equivalent methods in java.io.Console.[3]
>>>>>>>>> >
>>>>>>>>> > 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.
>>>>>>>>> >
>>>>>>>>> > Assume we start a student out here
>>>>>>>>> >
>>>>>>>>> > void main() {
>>>>>>>>> >     println("Hello, world");
>>>>>>>>> > }
>>>>>>>>> >
>>>>>>>>> > You can get through conditionals, loops, variables, methods, and
>>>>>>>>> return types before touching classes or access specifiers.
>>>>>>>>> >
>>>>>>>>> > int compute() {
>>>>>>>>> >     int total = 0;
>>>>>>>>> >     for (int i = 0; i < 10; i++) {
>>>>>>>>> >         total += i;
>>>>>>>>> >     }
>>>>>>>>> >     return total;
>>>>>>>>> > }
>>>>>>>>> >
>>>>>>>>> > void main() {
>>>>>>>>> >     println("Hello: " + compute());
>>>>>>>>> > }
>>>>>>>>> >
>>>>>>>>> > 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."
>>>>>>>>> >
>>>>>>>>> > enum Pirate {
>>>>>>>>> >    BLACKBEARD,
>>>>>>>>> >    OTHER
>>>>>>>>> > }
>>>>>>>>> >
>>>>>>>>> > record Pos(int x, int y) {}
>>>>>>>>> >
>>>>>>>>> > Pos treasure(Pirate pirate) {
>>>>>>>>> >     switch (pirate) {
>>>>>>>>> >         case BLACKBEARD ->
>>>>>>>>> >             return new Pos(5, 5);
>>>>>>>>> >         case OTHER ->
>>>>>>>>> >             return new Pos(0, 0);
>>>>>>>>> >     }
>>>>>>>>> > }
>>>>>>>>> >
>>>>>>>>> > void main() {
>>>>>>>>> >     println(treasure(Pirate.OTHER));
>>>>>>>>> > }
>>>>>>>>> >
>>>>>>>>> > 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.
>>>>>>>>> >
>>>>>>>>> > As originally pitched, this transition would have just meant
>>>>>>>>> wrapping the whole program in class Main {}, but now to make the transition
>>>>>>>>> from
>>>>>>>>> >
>>>>>>>>> > void main() {
>>>>>>>>> >     // Arbitrary code
>>>>>>>>> > }
>>>>>>>>> >
>>>>>>>>> > to
>>>>>>>>> >
>>>>>>>>> > class Main {
>>>>>>>>> >     void main() {
>>>>>>>>> >         // Arbitrary code
>>>>>>>>> >     }
>>>>>>>>> > }
>>>>>>>>> >
>>>>>>>>> > 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.
>>>>>>>>> >
>>>>>>>>> > import static java.io.IO.*;
>>>>>>>>> >
>>>>>>>>> > import module java.base;
>>>>>>>>> >
>>>>>>>>> > class Main {
>>>>>>>>> >     void main() {
>>>>>>>>> >         // Arbitrary code
>>>>>>>>> >     }
>>>>>>>>> > }
>>>>>>>>> >
>>>>>>>>> > My gripe is that the concepts introduced here - static, module,
>>>>>>>>> and * imports  - would have had no place to be introduced earlier.
>>>>>>>>> >
>>>>>>>>> > 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.
>>>>>>>>> >
>>>>>>>>> > // For every program up until this, they could freely access
>>>>>>>>> this from anywhere
>>>>>>>>> > int count = 0;
>>>>>>>>> >
>>>>>>>>> > // And they could freely make an instance of any inner class
>>>>>>>>> > class Other {}
>>>>>>>>> >
>>>>>>>>> > class Pos {
>>>>>>>>> >     static Pos of(int x, int y) {
>>>>>>>>> >         // So the rules they are used to don't apply anymore
>>>>>>>>> >         // and the explanation as to why really lies *after*
>>>>>>>>> they understand
>>>>>>>>> >         // what an anonymous main class is and does
>>>>>>>>> >         // ...
>>>>>>>>> >     }
>>>>>>>>> > }
>>>>>>>>> >
>>>>>>>>> > void main() {
>>>>>>>>> >    // ...
>>>>>>>>> > }
>>>>>>>>> >
>>>>>>>>> > 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.
>>>>>>>>> >
>>>>>>>>> > 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.
>>>>>>>>> >
>>>>>>>>> > Just as a hypothetical, say java.io.IO was java.lang.IO. No new
>>>>>>>>> import rules needed and now IO is available to all programs.
>>>>>>>>> >
>>>>>>>>> > void main() {
>>>>>>>>> >     IO.printLine("Hello, world");
>>>>>>>>> > }
>>>>>>>>> >
>>>>>>>>> > 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
>>>>>>>>> >
>>>>>>>>> > 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."
>>>>>>>>> >
>>>>>>>>> > 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.
>>>>>>>>> >
>>>>>>>>> > What am I overlooking?
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > [1]: https://openjdk.org/jeps/477
>>>>>>>>> > [2]:
>>>>>>>>> https://download.java.net/java/early_access/jdk23/docs/api/java.base/java/io/IO.html
>>>>>>>>> > [3]
>>>>>>>>> https://download.java.net/java/early_access/jdk23/docs/api/java.base/java/io/Console.html#print(java.lang.Object)
>>>>>>>>>
>>>>>>>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20240602/6e5f688a/attachment-0001.htm>


More information about the amber-dev mailing list