Hacker News new | ask | show | jobs
by jimbokun 828 days ago
Maybe my favorite feature in this release:

https://openjdk.org/jeps/463

Finally solves the inscrutable Hello World program!

Yes, it's just ergonomics for early beginners. But could be the difference in whether or not someone new to programming sticks with Java or not.

17 comments

C#'s got even better version of this feature since Nov 2021. Hello world is just a true one-liner.

https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals...

I really disliked this the first time I saw it. I was like "WTF is this?"

I can only think the reason why they did this was to compete with python, as our scripting languages that do not require a main/Main entry point.

Personally, it just feels wrong for compiled-based languages.

I think they could improve on C# with their namespace. Rather, for example, a typical C# file looking like:-

  using EFG;
  namespace ABC
  {
    public class XYZ
    {
     
    }
  }
They could just :-

  using EFG;
  using namespace ABC;
  public class XYZ
  {
    
  }
Pretty much taken from the C++ way.. but it saves on space availability.
The second option is what C# defaults to since a few versions ago.
Correct -- was added since .net 6, I believe.
Namespace declarations have been a thing in C# for a while
Yep. Point is it should have been added since Framework 4.
I 1000% agree. Though, a favorite early programming memory of mine was when static methods finally clicked and I went back and looked at all that boilerplate that meant nothing to me and it all became crystal clear what it meant and why it had to be like that.
This reminds me of when I finally understood why returning 0 from a function named main made sense.
And why array indices start at 0 instead of 1, in many, though not all, programming languages.
Actually a nice feature.

This solves the public static void main string args issue.

Still if I need JVM then Scala or Kotlin are still preferable over Java.

Obligatory Java for the Haters in 100 Seconds: https://www.youtube.com/watch?v=m4-HM_sCvtQ

> Still if I need JVM then Scala or Kotlin are still preferable over Java.

That's so 2010. I would avoid Scala like plague. It is a soup of all features imagined and some more. Java is difficult for novice. With Scala even experienced senior devs can look into a snippet and be befuddled. It is designed by academicians who thought clever looking choice is better.

About a decade ago, some Scala library authors thinking that "everything is better as a DSL" gave Scala a reputation for being a hieroglyphics soup, but that cannot be farther from the truth today. It's a really nice language to learn and to use, and the only one in my experience that I would want to take with me to scale from a quick dozen-liner script bash-style to a highly concurrent, highly available server application, from native to jvm to JS.

And the foothold in academics has some practical perks, too, like a sound type system (DOT calculus), compatibility guarantees at a theoretical level (TASTy), and what's cooking in the area of capture checking might be a general solution to many of the industry's biggest challenges (e.g. colorless asynchronous programming, safe errors, safe resource management, ... Think of Rust's borrow checker as a special case of this, and the consequences for scala-native as a systems programming platform).

> It is designed by academicians who thought clever looking choice is better.

That's just not true. That's the typelevel ecosystem. The official Scala toolkit mostly includes haoyi libraries which is pretty much Python like Scala.

I've never seen a java codebase I thought couldn't be better in kotlin
For reading it, I believe that. For authoring it, yikes it is slow. I'd guess due to all the implicit and implied and coercion and ... and ... and. Now I'm cognizant that I'm running my mouth without trying it on 1.9.x and a similarly recent IJ so maybe it got infinitely better, but my life experience with languages is that they only get more fancy swooshings not QoL improvements due to Moore's Law and yearly refresh cycles

I was/am always glad to pay that tax because non-null-by-default and the vastly superior val/var keyword pairs are totally worth it but it for sure is not a drop-in replacement in team environments. I am already constantly battling the vscoders (to say nothing of vimers) whining that "IJ is too slow for my eeee-leeeet typin'"

Definitely also for writing it.
Looking forward to JetBrains proposal to rewrite Java Virtual Machine into Kotlin Virtual Machine, certainly the existing Java codebase would be largely improved.
I really dislike this feature.

It's better to just say "we will come to this concept later", rather than make a fake syntax that does this (taken from the JEP) behind the scenes:

new Object() { // the implicit class's body }.main();

It adds more confusion, as you are left explaining that you could not really run an instance method without instantiating the class -- it was just something fake for beginners.

I agree. Coming from NodeJS I appreciate how explicit Java is. The complexity is there either way, but in Java it's right up front where I can see it, not hidden away under layers of abstraction for a supposedly better DX.
The thought process leading up to this work

https://openjdk.org/projects/amber/design-notes/on-ramp

My first Java programming course went over in detail about that piece of code and in a couple of hours taught me a lot of important Java concepts right away. Consider me not enthused about it.
Simple code like that kept pulling me back to the JSL 1.0 spec time and time again as my understanding deepened, much like the old singleton pattern debates of old.
This is nice for beginners, but the confusion is only postponed, because then you'd have to learn why you need to write a class as a container for static methods and that these methods must be static. So, the Java developers created another special case in the language.

Compare that with Kotlin where you have top-level functions, so that `main` is just like any other function.

They almost caught up with C#, which ditched requisite class declarations years ago. Although C# went one step further and allowed top-level code outside of methods, so that hello world is now:

   Console.WriteLine("Hello, world!")
You can write write code outside of methods in a Java class, called an initializer block:

  class MyClass {
    {
      System.out.println("Hello World!");
    }
  }
This will run when an object of the class is instantiated. So not useful for the case in question (you could get rid of the class declaration but would presumably still need a main method).

(It's also pretty poor style, but occasionally useful in a pinch, like when instantiating an anonymous inner class, which has no constructors that take arguments)

It has been a few years, but top-level statements in C# are still a fairly recent thing (C# 9 in 2020).
That sounds a lot like Top-level Statements in the .Net world. Personally I don’t use that feature because I’m old and get confused if things are magic but can certainly see the benefit for the newer devs.
I’m also a somewhat old school C# dev and the main reason I don’t use top level statements is that they only work in a single file of an application, so that single file is different from every other file in your solution.

It’s okay if you’re only writing a single file, and it really seems intended for beginners or micro applications, but for those of us writing anything besides the most trivial, it’s merely “cute” and just adds inconsistency.

Yeah, no doubt inspired by the .NET feature. I use it all the time for throwaway console apps.
This is exactly what I've been calling the "public static void main problem" for years (and an illustration of why I thought something like BASIC or Python should be everyone's first programming language). Neat to see the Java team come up with a solution for it. But "public static void main" runs deeper, and has to do with immediacy: shortening the time between the programmer giving instructions to the computer and seeing the results of those instructions being executed. It makes the smallest possible Java program greatly simpler and absent unusual comments that beginning programmers might struggle with; but there's the issue of the compilation step as well! If they make Java REPL-driven they might well have a winner!
Java has had the ability to run a single code file directly by running `java <path-to-file.java>` since Java 11 - https://openjdk.org/jeps/330. And it's had a Java REPL since Java 9.
Good that they got rid of the class/public static void/string[] Args boilerplate, but if they just went one step forward and declared implicit main function as top-level scope of a file, we could've got to a Python level of tersity. Just imagine!

    System.out.println("Hello world!");
To be that guy, not quite a python level of tersity!
Well, if they added System.out in the default context, it could've been just

    println("Hello world!")
I think that's as far as you can go.
# Python 3

p = print # the print() function

# Now we can do:

p("Hello world")

# endlessly, in this file.

Shorter by 17-odd characters than the above Java version.

I really doubt that. Java is complicated enough that it's not beginner friendly even if you don't have to write the class to put main into.

Given these are still methods of classes this JEP seems pointless to me. Not having to write class x {} isn't a great time saver.

Maybe in another ten years they'll remove System.out.println and allow for a simple println to be used.

Or maybe we'll all move to Kotlin by then.

You can statically import System.out if you are so inclined.
You can but for a new user that is even more of a barrier than writing out System.out.println
this will probably show up in java 23, ctrl + f "simpleio"

https://openjdk.org/jeps/8323335

And create the Kotlin Virtual Machine, with a Kotlin based ecosystem?
With respect, not hostile to beginners but adding complexity to the build to support this kind of implicit sugar, when beginners are 100% going to be using AI to write code and answer questions- seems like not the right tradeoff in 2024.
Well, they reduced a few lines of boilerplate for hello world Java program, while adding many many paragraphs of text to explain it. ;)
love this!
Java continues to evolve to a bad Groovy.
Groovy itself is a bad Groovy.
bad opinion is bad

I get gradle is a disaster (but that's more of a poorly managed and evolved DSL problem)

But ... does anyone use Spock and think "groovy sucks"? Yeah, I doubt it.

Raises hand Here! I have to work with Spock on a Java codebase and I think groovy sucks ;-)
Yeah I use Spock and Groovy all the time, good god does it suck big ones.
I hate to be "that guy" but ... raises hand.

Spock is also a DSL disaster that's trying to be ScalaTest (https://www.scalatest.org/user_guide/property_based_testing) but in a dynamic language. Every time I use it I have to re-learn the syntax. (I have the same issue with Gradle, so maybe it's just-me?)

My problem with gradle is I never use it enough to get familiar with it, once the problem is solved I promptly forget everything.
It's the perfect example of a bad DSL.

A "DSL" like SQL that you use hundreds of times a year you'll learn the model of.

A DSL like groovy that you use once for project setup (and for that you'll one-off it likely and stackoverflow the rest of the question) is not. And it isn't really natural, it's a bunch of arcane steps that at the end might superficially look a bit consistent, but still really isn't.

Groovy really needs an autocompleter or a generator. Or, well, as you say, you stackoverflow for everything outside the very vanilla basics of it.

But good luck getting the right version match to the syntax you need. Christ.

How so? I don't think there are many good things to say about Groovy, but I generally agree with most new features introduced to Java. What do you think Groovy does better?
- String interpolation

- triple-quote strings / blocks

- minimal class boilerplate (this posting)

- closures (Java closures are worse IMO)

- usable hashbang for UNIX

- I think java has strings in switch now, don't they? Do they have expressions?

WAIT, does Java STILL force you to write getter/setters?

features that make strings easier to use are bad in my opinion. the number one problem in java is people circumventing the type system with strings.

switch on strings is there, as are switch expressions.

records now removes the need for getters in immutable contexts.

But Java has all those features...?
Oops, sorry those are features java "stole" from groovy.

Java has the nullsafe operator now and the elvis too, doesn't it?

I don't use the spaceship operator much, implicit sorting works pretty well.

Groovy's closures have a lot less GOTCHAs. They simply work as expected, at least to me. Half the time I use java closures and I get complaints in compilation that I don't get in Groovy, but maybe they've improved closures more.

Groovy's GPars library is the bomb for concurrency/parallelism. I don't know if I could function in normal java constructs.

The .with keyword is a sneaky useful technique where you can declare a piece of data like:

"some cli command" .with { it.execute} .with { /* parse output */ }

It allows chained calls that flow naturally. Groovy generally allows pretty compact flowed calls which makes scripts a lot easier.

Groovy scripting with implicit vars is a lot easier than any java scripting, even with the "simplification" described.

The shorthand access/navigation of nested lists and maps, and the map / list literals (also taken by java at some point I think) are really nice to have. Also a + operator for lists and maps I use a lot

Groovy's ability to generically call methods without mucking through 10 lines of reflection is sometimes nice.

The auto-gen of getter/setters is a must have, I think Kotlin has those too?

CompileStatic lets me selectively use full java speed without groovy overhead.

In general, I like Groovy because it is typing-optional. Python and Javascript suck because they don't really have optional type enforcement. Java sometimes asks for too much typing. Groovy lets me select as needed.

The actual sane = for string assignment and == for sane string comparison is nice.

But honestly, Java with the listed features is a lot better. I'll probably still use groovy for doing what would normally done with bash (UGH) since I have a big CLI/scripting library base that handles argument parsing, json, encode/decode, encrypt/decrypt, zip/unzip, in nice compact syntax.

Groovy is basically a dead language now anyway. The world is overrun by JavaScript and Python, and AI looms to replace us all with horrid AI python or javascript glue code.

You can be really productive, expressive and performant in Groovy. So much of the language still works well with @CompileStatic and doesn’t require dynamic typing. Writing clear code that has decent refactoring support in IntelliJ.

Don’t forget traits! When are we getting traits in Java? Probably never.

Optional semicolons and parentheses to cut the line noise and enable internal DSLs.

Though Java has improved implicit typing with `var` and now we have reasonable lambdas, Java is still not a high-level language, but maybe it is now medium-high.

> Oops, sorry those are features java "stole" from groovy.

Well, yeah? Java's explicit strategy for the last few decades is to let other languages experiment, then implement the ideas that worked out once the dust has settled.

Hashbang aside this is a solid description of a base feature set of C# :D
A form of string interpolation is in this release.