I am amused by this:<p>> Worse, the early exposure to static methods will turn out to be a bad habit that must be later unlearned.<p>I have been using Java since 1.0 and it is my default language. I am writing Java code today.<p>I write functions using ‘static’ all the time. I prefer that a function be static. It shows that it does not depend on state of the enclosing object. Using ‘static’ on methods is not a bad habit. Having static fields and state is to be avoided.
I always love seeing Brian Goetz’s articles, they explain the problem succinctly and they do a great job of validating their approach, showing the shortcomings of alternatives.<p>I especially like the language team’s very conservative attitude, valuing backwards compatibility greatly. Here, they again solve most of the problem by simply changing the “program launcher” code, without any modifications/special casing done on the language level. For the rest, we will see. I think foregoing public requirements is a no-brainer, the rest may need a bit further thought based on further comments, here is the mailing list: <a href="https://mail.openjdk.org/pipermail/amber-spec-observers/2022-September/003724.html" rel="nofollow">https://mail.openjdk.org/pipermail/amber-spec-observers/2022...</a>
Applause! However, it's not always about "saving keystrokes"... it's about lowering accidental complexity and making code easier to reason about by requiring less cognitive load on the reader.<p>Another example: the lack of literals for collections in Java. Imagine this:<p><pre><code> Map x = {"a": "A", "b": "B"}; // not Java
</code></pre>
vs:<p><pre><code> Map x = new java.util.HashMap();
x.put("a", "A");
x.put("b", "B");
</code></pre>
The first case is more declarative, and thus easier to grasp.
In the second case you have to read, parse and "execute" line by line in your head... (Does ordering matter? Does line 3 depend on line 2?, etc).<p>When things like these compound, you end up with code-bases many times bigger and harder to grasp than in other languages.<p>Granted: you can write shitty code in any language, nothing will save you from that... But I think Java makes it harder to write simple and concise code, even to experienced coders.<p>Then there's also the "cultural" thing many already mentioned ("enterprise Java")... which is very real, but no JEP/JSR will fix that ;-).<p>Brian shows brilliance, even at "trivial" issues. I trust his judgement :-).
I like the idea of simplifying the main method, but it's honestly not a huge barrier as a high school teacher. Most IDEs will fill in the declaration of main for you, and I think it's perfectly fine to tell students "we'll worry about that later, write your code in the braces" without diving in to all the details. To me, what would be more helpful is an easier way to read input from stdin during a program. I usually give my intro students a static class that wraps Scanner, but it's a bit of a pain.
When i read the title, I thought they were finally going to fix gradle or improve maven. Those are the real on-ramps and they are a much bigger barrier to entry than main().<p>A cleaner/simpler alternative was Kobalt, but it’s now abandoned. A simple, official build tool would make the ecosystem easier to learn.<p><a href="https://github.com/cbeust/kobalt" rel="nofollow">https://github.com/cbeust/kobalt</a>
Confused about the criticisms now. Otherwise everybody complains about Java boilerplate. Remove some of it and make it optional, to avoid bogging down newbies in irrelevant details in the first instance, and further lead to less boilerplate to make simpler applications in the second instance (or further down the line). I'm not seeing a massive amount of effort being expended here, and I don't see how it's being wasted.
Another option is any classless java file is just a class with the same name as the file implementing Runnable.<p>E.g. Foo.java<p><pre><code> println("foo")
</code></pre>
Becomes:<p><pre><code> class Foo implements Runnable {
void run() {
System.out.println("foo");
}
}
</code></pre>
Then running java Foo.java instead just stubs a main() that looks like:<p><pre><code> class Main {
void main() {
new Foo().run();
}
}</code></pre>
Not a Java dev here, at least in part because the amount of ceremony to do trivial things seems excessive.<p>My understanding is that the ceremony and redundancy is deliberate. You type the same meaning multiple times so the compiler can detect inconsistencies and tell you about them. I.e. it's a feature, not a bug. Slightly analogous to type annotations or unit tests, one wants to write the redundant information in exchange for compiler diagnostics.<p>Syntactic sugar to make the language less annoying to work in is opposed to that goal, hard to guess if that's better for the target market.
This seems to be a weird micro-optimisation. While I agree with some of the goals (classless files, parameterless main exist in Kotlin and are nice to have), they should, in my opinion, not be implemented for the sole purpose of making `main` as minimal as possible.<p>I don't think you need to understand every single character of your very first program right from the beginning. A few of the concepts can be hand waved away to be explained in a later chapter without impeding the overall understanding of programs once you left the sub-twenty-lines beginner programs.
C# has this on their new ASPNET 7.0 docs. To have a single Program.cs file with all the builder and app code . incredibly accessible to a new learner of the framework.
This is still too long. I think C# already supports top-level execution (eg, your program is assumed to be main() as do almost all other languages). `println` is also a bad name for something that could just be `log` or `print`.
I’m actually very happy to see this after using Java for many years. I definitely had all of the mentioned thoughts about the keywords, and not knowing what they do when first learning.<p>Java needs staunchly maintain its static type nature rather than move towards a ‘everything is a string/array whatever’. The concept of types are not only powerful, performant, but they are way to grasp conceptually because the Java semantics and compile time checking.<p>I do wish CDI (or SpringFramewotk) was brought into CS and similar degrees. Dependency Injection brings a large number of good habits to developers, but it is a concept that is hard to teach as an employer. In our onboarding program, we have to teach people about the CDI container (a program ruining your program) managing all of your state for you (to great benefit and speed of development). During this time, we’re not getting much value out of the developer, and the teacher is also away from their normal duties as well. :/
<i>The declaration of a class and the incantation of public static void main is pure mystery to a beginning programmer.</i><p>This article misses the point, however. The problem is not writing your first hello world. The ceremony is not so much in the language itself but in the infrastructure. The verbosity of the language is just the tip of the iceberg.<p>I think Java back in the 90's started out actually quite decently, although from the get-go it had the verbosity. But at least it didn't have everything else yet that you're expected to know for any non-trivial program.<p>The first time the word "enterprise" appeared together with Java was the moment it went all downhill.
Sounds like great improvements. I would wish for the ramp to be extended a little bit to also do something about packages, for example allowing a common prefix like "com.company.project.whatever" to be elided, so that we don't have to go from "src/Hello.java" straight to navigating the maze of "src/main/java/com/company/project/whatever/hello/Hello.java".
I wrote up an alternative proposal here:
<a href="https://blog.joda.org/2022/10/fully-defined-entrypoints.html" rel="nofollow">https://blog.joda.org/2022/10/fully-defined-entrypoints.html</a><p>My concept is much more powerful by having a new kind of class declaration alongside 'record' and 'enum' - 'entrypoint'.
I have long considered that having to have the class definition explicit in the file is redundant, especially as the 2 have to have the same name anyway. Obviously if you need to `extend` or `implement` then an explicit declaration is needed. But otherwise, just defaulting to the file base name is more than sufficient.
I remember when first learning Java in 1995, and already being familiar with OOP from C++, I found it curious that such an OOP-focused language didn’t represent a program 1:1 as an object instantiated and initialized at load time, with a <i>main</i>/<i>run</i> method invoked on it to start execution. The choice of having <i>main()</i> be static was made even weirder by its still having to be defined within a class. Then if you’d want to have your application be an object, you’d have to do the extra `new MyApp(args).run()` bit manually, and have <i>run()</i> be the “real” main method. It all seemed very backwards.
I wonder - why he has not take it a step further and propose to get rid of return type (void) also? It would look even more slick (add optional semicolons and we will get javascript out of this :)).<p>main() {
println("Hello World");
}<p>I know that this notation is traditionally reserved for constructors but I'm not 100% sure why we cannot differentiate between methods and constructors just by looking at class name?
Doesn't Groovy (<a href="https://groovy-lang.org" rel="nofollow">https://groovy-lang.org</a>) achieve much of this? I remember being taught with it at university for some time before they introduced Java. With Groovy you don't need the class or main method, and can have a program which is just `println "Hello world!"`.
One additional comment: they need to make the launch protocol for jar files, much simpler as well. META-INF needs to be replaced with a simple properties file that indicates what method to run and which libraries to have on the class path.
Kotlin's syntax is cleaner in some most places, more explicit in some places (no implicit nulls, and wrt generics) and much terser when using naked functions etc.<p>Did Java's papa get jealous?