From amaembo at gmail.com Thu May 8 08:32:24 2025 From: amaembo at gmail.com (Tagir Valeev) Date: Thu, 8 May 2025 10:32:24 +0200 Subject: Simplified main methods -- what IDE users should expect? Message-ID: Hello, dear experts! This discussion is not exactly about Java specification, but I think we have the right people here for this topic. The Java IDEs usually provide a way to automatically generate a main method using some kind of template named 'main' or 'psvm' (which is short for 'public static void main'). Historically, invoking such a template generated a code like this: public static void main(String[] args) { } However, when 'Compact Source Files and Instance Main Methods' feature (JEP 512) is available, this doesn't look like a good default anymore. Some of our colleagues advocate that keeping the old signature is good because this is what people get used to, but I think we should reconsider this. Now we have multiple ways to generate a main method: - 'public' may be present or not - 'static' may be present or not - 'String[] args' may be present or not So technically we have eight different variants. What would the user expect by default? In my opinion, 'public' is simple: we should just drop it, as it doesn't add any value. This reduces the number of options to four. The 'static' modifier is more difficult. 'static void main()' and 'void main()' have different semantics: the latter involves automatic class instantiation, it makes the main() method inheritable (so inheritors if any may become launchable), and it requires a no-arg constructor. We cannot generate `void main(){}` inside the class that contains no default constructor, as this method will be non-functional and users might be surprised and confused. We might consider adding the `static` modifier only in classes without no-arg constructor, but this might be inconsistent, as users might not understand why sometimes `static` is generated and sometimes is not. Another case is implicit classes where `static` looks really alien, and we never have problems like no-arg constructors or inheritors. So I lean toward generating 'static' by default for explicit classes (regardless of its constructors) and no 'static' for implicit classes. However, I'm not sure that it's the best solution. Skipping 'String[] args' by default seems nice, but it will worsen the experience of people who actually need the args, as they will probably need to type more. We can assume that the variable named 'args' is implicitly available inside the method body, so the user may use it via autocompletion, and upon the first use, it will be automatically added to the method signature. This is possible but somewhat weird: users should know in advance that something named 'args' can be used, even if it's not explicitly available in the code. We can also create several templates (something like 'maina' for main with arguments and 'mains' for static main), but this also complicates things and increases the cognitive load to the users. Also, different IDEs may solve this differently, and this may add confusion for people who change IDE sometimes. I would be glad to hear your opinions. What would you expect from your IDE when generating a main method in Java 25? With best regards, Tagir Valeev -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Thu May 8 11:07:34 2025 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 8 May 2025 13:07:34 +0200 (CEST) Subject: Simplified main methods -- what IDE users should expect? In-Reply-To: References: Message-ID: <1958673543.258797749.1746702454704.JavaMail.zimbra@univ-eiffel.fr> Hello Tagir, for me, you need another template, let's call it "main", which is a little smarter than psvm. First, i would keep "psvm" as is, because psvm literally means "public static void main" so the intent of the user is clear. Then for the new template "main", i would take a look if main is invoked inside a class or not, if it's inside a class, I think "static void main" is a good default with public being added if the class itself is public. If there is no enclosing class, "void main" is a good default. Now, about adding the String parameter, i would if calling main should not result with the method main be generated (using the rule above) and the caret is in between the two parenthesis of the main, if a character is typed, then String[] is added and the character is the first character of the parameter, if the compeltion is used, the name "args" can be added, otherwise, the caret if moved inside the method. It's perhaps a little too smart for beginners, so perhaps the "smart insert" of the argument should only occur when there is a class ? regards, R?mi > From: "Tagir Valeev" > To: "amber-spec-experts" > Sent: Thursday, May 8, 2025 10:32:24 AM > Subject: Simplified main methods -- what IDE users should expect? > Hello, dear experts! > This discussion is not exactly about Java specification, but I think we have the > right people here for this topic. > The Java IDEs usually provide a way to automatically generate a main method > using some kind of template named 'main' or 'psvm' (which is short for 'public > static void main'). Historically, invoking such a template generated a code > like this: > public static void main(String[] args) { > > } > However, when 'Compact Source Files and Instance Main Methods' feature (JEP 512) > is available, this doesn't look like a good default anymore. Some of our > colleagues advocate that keeping the old signature is good because this is what > people get used to, but I think we should reconsider this. > Now we have multiple ways to generate a main method: > - 'public' may be present or not > - 'static' may be present or not > - 'String[] args' may be present or not > So technically we have eight different variants. What would the user expect by > default? > In my opinion, 'public' is simple: we should just drop it, as it doesn't add any > value. This reduces the number of options to four. > The 'static' modifier is more difficult. 'static void main()' and 'void main()' > have different semantics: the latter involves automatic class instantiation, it > makes the main() method inheritable (so inheritors if any may become > launchable), and it requires a no-arg constructor. We cannot generate `void > main(){}` inside the class that contains no default constructor, as this method > will be non-functional and users might be surprised and confused. We might > consider adding the `static` modifier only in classes without no-arg > constructor, but this might be inconsistent, as users might not understand why > sometimes `static` is generated and sometimes is not. Another case is implicit > classes where `static` looks really alien, and we never have problems like > no-arg constructors or inheritors. So I lean toward generating 'static' by > default for explicit classes (regardless of its constructors) and no 'static' > for implicit classes. However, I'm not sure that it's the best solution. > Skipping 'String[] args' by default seems nice, but it will worsen the > experience of people who actually need the args, as they will probably need to > type more. We can assume that the variable named 'args' is implicitly available > inside the method body, so the user may use it via autocompletion, and upon the > first use, it will be automatically added to the method signature. This is > possible but somewhat weird: users should know in advance that something named > 'args' can be used, even if it's not explicitly available in the code. > We can also create several templates (something like 'maina' for main with > arguments and 'mains' for static main), but this also complicates things and > increases the cognitive load to the users. Also, different IDEs may solve this > differently, and this may add confusion for people who change IDE sometimes. > I would be glad to hear your opinions. What would you expect from your IDE when > generating a main method in Java 25? > With best regards, > Tagir Valeev -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Thu May 8 12:57:35 2025 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 8 May 2025 08:57:35 -0400 Subject: Simplified main methods -- what IDE users should expect? In-Reply-To: References: Message-ID: Thanks for starting this discussion.? Indeed, I think it is good to have a fresh look at an empty IDE window, and see where we think it should go. First, I think the "but everyone knows public static void main, so we should keep it that way forever" argument is a bit silly.? We should guide people towards the best version of the language; many developers learn a lot about Java from the hints provided by the IDE. Let's skip over the "what should the defaults be" for a second, and talk about refactoring between the various versions.? IDEA already has hints for when `public` is unnecessary, such as the public modifier on instance methods.? It renders `public` in a lighter tone and offers a quick-fix to drop it.? It seems reasonable to do the same with `public` on main?? Similarly, if the class already has a no-arg constructor (or perhaps has _no_ explicit constructor, or an empty no-arg constructor), it can do the same with `static`, offering to vanish it for the user.? And with `String[] args`, if `args` is not used in the body, it can do the same with those. So separate from the question of defaults, a class with p-s-v-m that doesn't need public, static, or args, the IDE can guide us to a more minimal version of main.? That seems nice.? Similarly, for an instance main, or a main without args, I assume there will be quickfixes offered to add back `args` or `static`, in case the minimal main is not what the user wants.? With all this in place, even if the default is wrong, it is easy to incrementally navigate up and down to the "smaller" or "bigger" declaration as desired. I think your starting position of "no public" and "no args" is good.? I like your story about "guessing" whether the user wants an `args` variable; another possible heuristic, besides going strictly by name, is whether they use an undeclared array variable (such as on the RHS of foreach, or x.length, or x[i]), and offer a "was that supposed to be the arguments?" quickfix. Also, since there can now be multiple possible main candidates, I think another thing the IDE can help with is identifying when a method called `main` is _not_ the main method that the launcher will invoke.? (The "real" main method may be in a superclass now.) Static is the hard one.? "Instance main" is the least well known aspect of this JEP; it is hard to tell whether the community will adopt it as their default (I suspect some will, some won't, and there will be low-grade style wars about it.) > We cannot generate `void main(){}` inside the class that contains no > default constructor, as this method will be non-functional and users > might be surprised and confused. By "default constructor", you mean no-arg, right?? Because if you have _no_ explicit constructor, you get a free no-arg constructor, and are fine. > I lean toward generating 'static' by default for explicit classes > (regardless of its constructors) and no 'static' for implicit classes. > However, I'm not sure that it's the best solution. I think that's an OK starting point, but I might suggest to nudge you over into dropping the static if the class is sufficiently "empty" (no ctors, empty no-arg ctor, etc.)? I think there might be momentary confusion about "where's my static", but if so, that's a one-time learning opportunity, and thereafter it will be fine. As to `psvm`, my first thought is to keep psvm as is, for people who are used to it, but then the psvm declaration will immediately have dimmed out `public`, `static`, and `String[] args`, so users will see these are optional and may take the quickfixes to drop them.? And then have another macro for `main` (which is easier to remember anyway) that is the "smart main wizard" that declares the main method using the minimal set of gunk relative to context, being sensitive to the presence of an explicit class declaration or not, explicit ctors or not, etc.? But I can also see how it is nice to just guide people to the new Java with the old name.? So I think either way works here. Stepping back a step, I always get a new class window with ctrl-N, which asks me for a class name and fills in `public class Foo` for me.? Will the "new class" dialog have an option for "implicit class"?? (And, what do we call it?? The spec term "implicit class" will not necessarily be helpful to the target audience, since they may not know that's what they want.? Perhaps some sort of "new single file program" option?) On 5/8/2025 4:32 AM, Tagir Valeev wrote: > Hello, dear experts! > > This discussion is not exactly about Java specification, but I think > we have the right people here for this topic. > > The Java IDEs usually provide a way to automatically generate a main > method using some kind of template named 'main' or 'psvm' (which is > short for 'public static void main'). Historically, invoking such a > template generated a code like this: > > public static void main(String[] args) { > ? > } > > However, when 'Compact Source Files and Instance Main Methods' feature > (JEP 512) is available, this doesn't look like a good default anymore. > Some of our colleagues advocate that keeping the old signature is good > because this is what people get used to, but I think we should > reconsider this. > > Now we have multiple ways to generate a main method: > - 'public' may be present or not > - 'static' may be present or not > - 'String[] args' may be present or not > > So technically we have eight different variants. What would the user > expect by default? > > In my opinion, 'public' is simple: we should just drop it, as it > doesn't add any value. This reduces the number of options to four. > > The 'static' modifier is more difficult. 'static void main()' and > 'void main()' have different semantics: the latter involves automatic > class instantiation, it makes the main() method inheritable (so > inheritors if any may become launchable), and it requires a no-arg > constructor. We cannot generate `void main(){}` inside the class that > contains no default constructor, as this method will be non-functional > and users might be surprised and confused. We might consider adding > the `static` modifier only in classes without no-arg constructor, but > this might be inconsistent, as users might not understand why > sometimes `static` is generated and sometimes is not. Another case is > implicit classes where `static` looks really alien, and we never have > problems like no-arg constructors or inheritors. So I lean toward > generating 'static' by default for explicit classes (regardless of its > constructors) and no 'static' for implicit classes. However, I'm not > sure that it's the best solution. > > Skipping 'String[] args' by default seems nice, but it will worsen the > experience of people who actually need the args, as they will probably > need to type more. We can assume that the variable named 'args' is > implicitly available inside the method body, so the user may use it > via autocompletion, and upon the first use, it will be automatically > added to the method signature. This is possible but somewhat weird: > users should know in advance that something named 'args' can be used, > even if it's not explicitly available in the code. > > We can also create several templates (something like 'maina' for main > with arguments and 'mains' for static main), but this also complicates > things and increases the cognitive load to the users. Also, different > IDEs may solve this differently, and this may add confusion for people > who change IDE sometimes. > > I would be glad to hear your opinions. What would you expect from your > IDE when generating a main method in Java 25? > > With best regards, > Tagir Valeev -------------- next part -------------- An HTML attachment was scrubbed... URL: From amaembo at gmail.com Tue May 13 15:34:27 2025 From: amaembo at gmail.com (Tagir Valeev) Date: Tue, 13 May 2025 17:34:27 +0200 Subject: Simplified main methods -- what IDE users should expect? In-Reply-To: References: Message-ID: Thank you for your thoughts on this topic! > By "default constructor", you mean no-arg, right? Yes, shame on me. Sometimes I mix 'default constructor' (an implicit one) and an explicit no-arg constructor. We already dim the args parameter in the main() if it's not used and the language level allows omitting it. In future versions, we will dim public or protected on main if it's not called from anywhere (though sometimes searching the callers in the interactive editor in a huge project could be costly). We are still not sure whether we want to have different behavior for 'psvm' and 'main' templates, as so far they were synonymous. Also, in Kotlin, we also have 'psvm' which generates simply `fun main() {}` and people do not complain. There's also 'main' template which does the same, so probably people without Java background are simply unaware about 'psvm'. We are still not so sure about 'static' being redundant. We will mark it as such in implicit classes, but probably not yet in normal classes. With best regards, Tagir Valeev. On Thu, May 8, 2025 at 3:06?PM Brian Goetz wrote: > > Thanks for starting this discussion. Indeed, I think it is good to have a fresh look at an empty IDE window, and see where we think it should go. > > First, I think the "but everyone knows public static void main, so we should keep it that way forever" argument is a bit silly. We should guide people towards the best version of the language; many developers learn a lot about Java from the hints provided by the IDE. > > Let's skip over the "what should the defaults be" for a second, and talk about refactoring between the various versions. IDEA already has hints for when `public` is unnecessary, such as the public modifier on instance methods. It renders `public` in a lighter tone and offers a quick-fix to drop it. It seems reasonable to do the same with `public` on main? Similarly, if the class already has a no-arg constructor (or perhaps has _no_ explicit constructor, or an empty no-arg constructor), it can do the same with `static`, offering to vanish it for the user. And with `String[] args`, if `args` is not used in the body, it can do the same with those. > > So separate from the question of defaults, a class with p-s-v-m that doesn't need public, static, or args, the IDE can guide us to a more minimal version of main. That seems nice. Similarly, for an instance main, or a main without args, I assume there will be quickfixes offered to add back `args` or `static`, in case the minimal main is not what the user wants. With all this in place, even if the default is wrong, it is easy to incrementally navigate up and down to the "smaller" or "bigger" declaration as desired. > > I think your starting position of "no public" and "no args" is good. I like your story about "guessing" whether the user wants an `args` variable; another possible heuristic, besides going strictly by name, is whether they use an undeclared array variable (such as on the RHS of foreach, or x.length, or x[i]), and offer a "was that supposed to be the arguments?" quickfix. > > Also, since there can now be multiple possible main candidates, I think another thing the IDE can help with is identifying when a method called `main` is _not_ the main method that the launcher will invoke. (The "real" main method may be in a superclass now.) > > Static is the hard one. "Instance main" is the least well known aspect of this JEP; it is hard to tell whether the community will adopt it as their default (I suspect some will, some won't, and there will be low-grade style wars about it.) > > We cannot generate `void main(){}` inside the class that contains no default constructor, as this method will be non-functional and users might be surprised and confused. > > > By "default constructor", you mean no-arg, right? Because if you have _no_ explicit constructor, you get a free no-arg constructor, and are fine. > > I lean toward generating 'static' by default for explicit classes (regardless of its constructors) and no 'static' for implicit classes. However, I'm not sure that it's the best solution. > > > I think that's an OK starting point, but I might suggest to nudge you over into dropping the static if the class is sufficiently "empty" (no ctors, empty no-arg ctor, etc.) I think there might be momentary confusion about "where's my static", but if so, that's a one-time learning opportunity, and thereafter it will be fine. > > As to `psvm`, my first thought is to keep psvm as is, for people who are used to it, but then the psvm declaration will immediately have dimmed out `public`, `static`, and `String[] args`, so users will see these are optional and may take the quickfixes to drop them. And then have another macro for `main` (which is easier to remember anyway) that is the "smart main wizard" that declares the main method using the minimal set of gunk relative to context, being sensitive to the presence of an explicit class declaration or not, explicit ctors or not, etc. But I can also see how it is nice to just guide people to the new Java with the old name. So I think either way works here. > > Stepping back a step, I always get a new class window with ctrl-N, which asks me for a class name and fills in `public class Foo` for me. Will the "new class" dialog have an option for "implicit class"? (And, what do we call it? The spec term "implicit class" will not necessarily be helpful to the target audience, since they may not know that's what they want. Perhaps some sort of "new single file program" option?) > > > > > > > On 5/8/2025 4:32 AM, Tagir Valeev wrote: > > Hello, dear experts! > > This discussion is not exactly about Java specification, but I think we have the right people here for this topic. > > The Java IDEs usually provide a way to automatically generate a main method using some kind of template named 'main' or 'psvm' (which is short for 'public static void main'). Historically, invoking such a template generated a code like this: > > public static void main(String[] args) { > > } > > However, when 'Compact Source Files and Instance Main Methods' feature (JEP 512) is available, this doesn't look like a good default anymore. Some of our colleagues advocate that keeping the old signature is good because this is what people get used to, but I think we should reconsider this. > > Now we have multiple ways to generate a main method: > - 'public' may be present or not > - 'static' may be present or not > - 'String[] args' may be present or not > > So technically we have eight different variants. What would the user expect by default? > > In my opinion, 'public' is simple: we should just drop it, as it doesn't add any value. This reduces the number of options to four. > > The 'static' modifier is more difficult. 'static void main()' and 'void main()' have different semantics: the latter involves automatic class instantiation, it makes the main() method inheritable (so inheritors if any may become launchable), and it requires a no-arg constructor. We cannot generate `void main(){}` inside the class that contains no default constructor, as this method will be non-functional and users might be surprised and confused. We might consider adding the `static` modifier only in classes without no-arg constructor, but this might be inconsistent, as users might not understand why sometimes `static` is generated and sometimes is not. Another case is implicit classes where `static` looks really alien, and we never have problems like no-arg constructors or inheritors. So I lean toward generating 'static' by default for explicit classes (regardless of its constructors) and no 'static' for implicit classes. However, I'm not sure that it's the best solution. > > Skipping 'String[] args' by default seems nice, but it will worsen the experience of people who actually need the args, as they will probably need to type more. We can assume that the variable named 'args' is implicitly available inside the method body, so the user may use it via autocompletion, and upon the first use, it will be automatically added to the method signature. This is possible but somewhat weird: users should know in advance that something named 'args' can be used, even if it's not explicitly available in the code. > > We can also create several templates (something like 'maina' for main with arguments and 'mains' for static main), but this also complicates things and increases the cognitive load to the users. Also, different IDEs may solve this differently, and this may add confusion for people who change IDE sometimes. > > I would be glad to hear your opinions. What would you expect from your IDE when generating a main method in Java 25? > > With best regards, > Tagir Valeev > >