46 comments

[ 2.0 ms ] story [ 11.3 ms ] thread
2934 commits OMG... huge work.
There is just a high level of a professionalism around the whole project. Who is sponsoring all of this? Do they all work for Oracle?
How much of Valhalla is this? 50% of it? 90% of it?
If I understand this correctly then Integer becomes a value class and every instance of it loses its object identity.

I do not have a lot of knowledge about the details but from the outset it seems like a rather bold move to me.

As far as I understood this (plus future work) will make value classes work more like structs meaning it will save memory and align memory better for things like gRPC, etc.
Wait, what? Virgil targeting the JVM does rely on that to represent vacuous arrays like `Array<void>`. That's annoying.
What's the latest status? Is it still limited to 63-bits of data plus 1 bit for nullability?
(comment deleted)
I feel lonely in that: I mostly love Java as a language.

The lack of value types is the biggest impediment to certain types of performance. I am really looking forward to this evolution of the language.

java the language is amazing

the problem with it is entirely cultural. why is `IStatusChangeEntityCreationManagerFactory` everywhere?

and why are the frameworks so huge and all encompassing? i think batteries included rails-style frameworks are great, but when i wrote Java, it didn't feel like rails at all

none of these are language problems

What I love the most is the sheer amount of thought and philosophy put into Valhalla. It transcends the binary understanding of object vs value and actually defines 4 distinct buckets:

1: Classical Object

2: Object without identity

3: Atomic Value

4: Classical Value (Tearable)

Each bucket has clearly defined performance characteristics and semantic constraints. So depending on the nature of your data, you can always get some benefit from values even if you couldn't go all the way. This is a work of art.

You are not alone.

Java remains unfairly tethered to a reputation forged over 20 years ago. Human psychology reveals a reluctance to update our worldview: once a collective consensus solidifies, it becomes very difficult to dismantle. Yet, to dismiss Java today is to overlook a remarkable evolution. Modern Java is an elegant, highly capable language, resting upon the Java Virtual Machine, which is a remarkable piece of technology.

I used to love Java mostly for its batteries-included well designed standard library. Despite the verbosity of the language itself. But over time the language has really evolved a lot and gotten a lot more pleasing to the eye (in my opinion).
I don’t do programming for a living (i manage infrastructure) but i have a very fond memory of java from the earliest days of my career.

I really really think that java is weighted down by all the ceremonial enterprise stuff that has accumulated over the years.

Lightweight frameworks are somewhat recent, otherwise you really couldn’t print a text/plain http response without bringing up a whole application server and a whole ecosystem of libraries (j2ee)

Also… the build system situation is still shit

I've said this before but I'll say it again: The worst part of Java is Java programmers.

For most of my career, I thought I hated Java, primarily because every piece of Java code I had ever worked with was overly verbose across a million different files to do things that would take like ten lines of code in any other language.

Then I actually started looking at all the features for Java 8, 11, 17, and 21, and realized: NO! Java actually gives lots of really great tools and language features that allow you to write relatively pretty, terse, performant code. Record types help cut down on a lot of boilerplate stuff, the streams API allows for pretty work over lists, sealed interfaces mostly solve my itch for ADTs, virtual threads are genuinely pretty impressive bits of engineering, and for the stuff that isn't built in, Vert.x and Disruptor do a pretty good job filling in the gaps.

Once I learned all that, I was kind of mad at people still writing code like it was 1999, but also started to enjoy writing Java. It helps that by this time I was already senior and staff level, meaning I was given much more leeway in how code was written (so the poor junior engineers are stuck/blessed dealing with my code using all the shiny new features).

I agree fully. It may not be perfect but it works really well, has a huge community, and I like the language.

I mostly ignore online discussions about Java. So much of it just feels like memes. Complaining about things that haven’t been valid in a very long time. Sometimes almost 2 decades.

It feels a bit like people bashing Nickelback. It was the “cool” thing to do. Maybe they’ve never used Java. Or only for one college course.

People can dislike Java. I’m sure some do. It’s fine. But it seems like the anti opinion is really over represented/amplified.

You shouldn't be. I do like Java a lot, and recent changes (and speed of those) just makes it more and more better.

And I appreciate and I'm under huge awe to the amount of though put into the evolution -- instead of just cramming every new shiny thing they ponder it a lot to arrive at the most sensible option while trying their best to maintain backward compatibility -- kudos!

(comment deleted)
The tooling could be better, though.

I wish it came with more batteries included, and it renovated that old Java cli split per commands, following a bit what golang did:

- java run

- java build

- java test

- java fuzz-test

- java format

- java lock

- java lsp

- etc.

Along with a better support of posix long form flags like ‘--version’.

You’re not alone! I love Java too. It is excellent.

I don’t reach for it much anyone since I prefer TypeScript’s type system and the ability to use the same language for both client/server, but I’m never upset to write some Java :)

You are definitely not alone. I love Java and I will always defend it. Java's perception is tainted by baggage from decades ago.
It's pretty interesting that while both languages still receive new features, Java seems to stay ahead of JavaScript:

- Java has long had a modern replacement for Date, while JavaScript's recently standardized Temporal API still isn't supported in Safari.

- Java has switch expressions, while JavaScript, despite its Scheme influence, does not.

- And now Java is getting value objects, while JavaScript's equivalent tuples & records proposal has been withdrawn.[0]

JavaScript was not developed as a fork of Java, but much of its basic syntax still resembles Java, so I think it's fair to compare them.

[0]: https://github.com/tc39/proposal-record-tuple

Java is to JavaScript what a Car is to Carpet. Very different beasts, though a lot of V8 work was inspired by Hotspot that's just because of common VM patterns not the syntax of the languages.
I personally would never compare the two. Someone said: java to JavaScript is like car to carpet. And I completely agree with that.
> JavaScript was not developed as a fork of Java, but much of its basic syntax still resembles Java, so I think it's fair to compare them.

It's absolutely irrelevant to compare these two languages. Calling the former "Javascript" was just a marketing trick.

The withdrawn of that proposal made me so sad. It would be amazing for JS as language, specially with certain use cases.
JavaScript still doesn't have proper integers.
It's really nice to see movement here finally. Lack of value types has been one of the biggest performance pitfalls in Java for decades at this point
Really cool, shame that strings can’t be fully indistinguishable like Integer despite their immutability
I don't think there's a lot of gains to be had for strings. Perhaps if you are dealing with a very large amount of small strings then it could be useful, but once you get past a few characters strings it's faster to just send around a reference anyways.
One misconception I had was that with value objects we could simply use `==` for comparison. But it looks like there's lots of gotchas with this especially if the value class has String fields for one or more fields. For example, comparing two ZonedDateTime value objects may be fine with == because I believe the JDK team ensured the Strings that represent the ZoneIds are always the same reference.

We have tons of wrapper classes in our codebase which seem ideal as value objects. For example, instead of passing around "String emailAddress", we have a wrapper class EmailAddress. While we can now make our EmailAddress class a value object, we cannot do "==". Unlike ZoneId in which there's a fixed set and you can intern all ZoneIds in the string pool, email addresses are unique and trying to intern all email addresses would be a bad idea. So it seems like using .equals is here to stay even for these types of basic classes.

I'm always amazed by how much thinking and work the Java leads put in rolling out changes that move the language forward, but make it backward compatible as much as possible.
Rhis is the correct way to do it in enterprise environments.

C++ gets a lotof rage for doing the same thing.

The last thing you want in an enterprise environment is that your working code breaks and you have to commit more time to things that were working before.

That's great, even though specialized generics are still missing. I think these improvements will be especially beneficial for Scala, because it is such a powerful language, but abstracting on the JVM comes at a heavy price.
I keep forgetting the reasoning for this part of the design - why is the value semantics baked in the declaration site and not at the use site?

Why does the class author have to declare it as a value type? I know this has been rehashed before many times by Brian but I keep forgetting the reasoning.

I think it keeps going back to "preserving type invariants". Turning an object into a value can have surprising constraints on the integrity of the type. These include: forced empty constructor (for bulk initialiation in arrays), violation of cross-field invariance (think of a Range-type where "end" value is suddenly smaller than the "start" due to a data race), etc.

Java always had a focus on enabling library authors over empowering call-site users. And I think approach has proven its dividend.

> Generic types such as List<T> and Comparable<T> can be instantiated with value classes as the type arguments.

> JEP 218, Generics over Primitive Types (with revisions), will allow generic classes and methods to specialize field, array, and local variable layouts when parameterized by value class types.

Ok now this is cool! JVM needs more ways to use compile time known value sizes for better memory allocation and optimizations.

Modern Java friggen rocks. I honestly cannot understand why you would use anything but the OG these days!