The biggest feature in Java 21 is the release of Virtual Threads: <a href="https://openjdk.org/jeps/444" rel="nofollow noreferrer">https://openjdk.org/jeps/444</a><p>For some reason, this is missing from the article. If there was any feature that would sway existing Golang developers to switch to Java, it would be this. It would perhaps also convince the haters of the reactive-style concurrency patterns.
The title of the blog post is IMO a poor choice. The (hidden) subtitle of the post is "Algebraic data types in Java" which is much more descriptive of the content. A better title would have been "Algebraic data types in Java 21".<p>Perhaps because of the title, many/most of the comments here are off-topic. I was hoping to see more discussion about algebraic data types, strengths and weaknesses of the Java implementation, technical comparisons to other languages, etc.
The "Sealed classes" feature, as described here, just feels all wrong to me.<p>They are saying that if you have a (normal) interface, anyone can create a new class implementing it. So if you do<p><pre><code> if (x instanceof Foo) {
...
} else if (x instanceof Bar) {
...
} ...
</code></pre>
then your code will break at runtime if someone adds a new class, as that code won't expect it. So the article is saying the solution is to use the new "sealed" interfaces feature, so nobody can create any new classes implementing that interface, and your "if" statement will not break.<p>Surely object-oriented programming already thought about that and already solved that? (I know object-oriented programming is out of vogue at the moment, but Java <i>is</i> an object-oriented language.)<p>The solution there is to add a method to the interface, and all your classes implement that. Then rather than having a massive if/switch statement with all the options, you call the method.<p>That is better than preventing people from extending your code, it <i>allows</i> them to extend your code. They just have to implement the method. And the compiler will force them to do that, so they can't even accidentally forget.<p>The example given of color spaces (RGB, CMYK etc.) is a great example. I can absolutely imagine writing code which uses color spaces, but then some user or client having a need to use a weird obscure color space I haven't thought of. I wouldn't want to restrict my code to saying "these are the color spaces I support, due to this massive if/switch statement listing them all, the code is written in such a way that you can't extend it".
Nice article as someone familiar with sum types but not sum types in Java.<p>I don't know if sum types alone are enough to get me to like Java, pervasive nullability is still around and even rears its head multiple times in this article.
> Why do we call them product types anyway?<p>Answer in the piece is not wrong, but put more intuitively and succinctly: the total number of possible value (inhabitants) in a product type is the product of the quantity of inhabitants of the constituent types.<p>Replace the “product”s with “sum”s and it works too.<p>Interestingly, the total number of unique functions (judged only in terms of input and output) from a -> b can be found by exponentiation, (inhabitants of b) ^ (inhabitants of a).
I can't wait 'til Project Valhalla is complete and Java finally gets value types. Then with sum types, value types and goroutines it'll be one of the nicest languages out there.
java was never really a bad language.<p>the people were. if not massive over-engineering. too many abstract concepts that make it hard to grasp a codebase.<p>code voodoo - in the form of reverse GOTO statement i.e annotations<p>DI frameworks .<p>what needs fixing is not the language but the ecosystem. there needs to be a "reformation" movement within the java ecosystem.<p>yeah people migrating to kotlin or clojure or scala isn't enough.
The author cites this to justify the need for Records:<p>> Most Java objects set every field to be private and make all fields accessible only through accessor methods for reading and writing.<p>> Unfortunately, there are no language enforced conventions for defining accessors; you could give the getter for foo the name getBar, and it’ll still work fine, except for the fact that it would confuse anybody trying to access bar and not `foo'.<p>Scala supports pattern matching on objects implementing the `unapply` method.<p>Is this considered harmful? Why didn’t Java follow this route?
Java was always a great language. It's the enterprisy ecosystem that make me want to throw up. To implement a line of logic, I have seen dozen classes and interfaces.
道生一,一生二,二生三,三生萬物。萬物負陰而抱陽,沖氣以為和。<p>The Function gives birth to the Unit type. The Unit type gives birth to the Boolean. The Boolean gives birth to the Value type. The Value type gives birth to the Top type. Each Top type contains 0s and 1s, thereby bringing harmony to the computation.
Golang is simple, smart and opinionated subset of Java/C#.<p>Everything moves slowly in corporate world. It will take another at least 2-3 years for large community of Java ecosystem and average devs to adopt Java 21 and capabilities.
the argument for Java seems to be that it's gradually gaining features we already have in Scala, Kotlin, OCAML, F#, etc... so why not use the languages that have those features today?
Sad this gets to front page while a blog post which documents that .NET 8 has 200 A4 pages worth of performance improvements gets absolutely ignored.<p>C# keeps being the language people are looking for but don't know about.
The problems with Java can't be fixed by adding new things, you can't undo decades of ecosystem development, training, and ideology built on top of the idea that inheritance is really good idea and belongs everywhere.<p>edit: I will say that as a Java developer I am grateful every day for the improvements to the language. Java is a very impressive language and I have a lot of respect for the people working on it.
> This set of changes allows Java to express one of the foundations of functional programming that the language never could before - Algebraic data types, along with idiomatic ways of using them.<p>And here I thought the foundation of functional programming was <i>functions</i>, which Java still doesn't have.<p>Seriously, functional programming is about functions, not types.
Finally Java catching up with some basic features that Scala has for 10 years or so. Hoping that more good stuff from Scala will get into Java soon, maybe at some point I can try to use Java again. :-)
Has anyone used virtual threads? I tried to migrate my app over to VT's and kept experiencing random deadlocks and I couldn't figure out what was causing them. I tried moving all the synchronized blocks to reentrant locks, but that didn't work. I also tried turning on the TV debugging system properties, but none of them printed the problem.
The biggest problem with Java is... the walled garden, the snob society, the elitist, exclusive culture.<p>Go isn't like that, or at least wasn't when G+ was still around.<p>Nowadays I don't get in touch much with people, but when I create issues Go people are usually not as unfriendly as Java/JVM people.