Java sealed classes and exhaustive pattern matching
Posted by hnisjafx40 4 days ago
Comments
Comment by smarks 3 days ago
[1]: https://openjdk.org/jeps/524
The article points out a potential pitfall with how this version of the API exposes a sealed class. If the application has an exhaustive switch expression that lists all permitted subclasses, and a later JDK release were to add a new permitted subclass, this would potentially expose the application to a MatchException at runtime.
In the JDK 27 version of the PEM Encodings API, JEP 538 [2], we’ve adjusted the permitted subclasses of the sealed class in question to include a non-public permitted subclass.
[2]: https://openjdk.org/jeps/538
This prevents applications from using an exhaustive switch expression by enumerating all permitted subclasses. This allows the JDK to extend set of permitted subclasses in the future without exposing applications to the risk of unexpected exceptions.
Comment by misja111 3 days ago
Comment by masklinn 3 days ago
Defaulting to exhaustive pattern matches is correct, it’s by far the most frequent case (which is why essentially every modern language does that); being able to prevent exhaustive matching is useful for libraries; and using a private subclass is a completely obvious way to implement that in Java.
See private extensible variants for the same capability in OCaml. Or the non_exhaustive attribute in Rust. Or the nonexhaustive attribute in Swift (or alternatively opting into library-evolution which reverses the defaults).
Comment by rf15 3 days ago
Comment by misja111 3 days ago
This will nullify the advantage of being able to treat sealed classes as algebraic datatypes by using the exhaustiveness check.
Comment by rf15 3 days ago
I feel this is fundamentally a perspective issue. If this is a problem, also consider why people want sealed classes in the first place. It's always a tradeoff and you can also always fork or propose your own improved version of the concept and see if it has enough merit to gain traction. There's a million other footguns in the language that needs similar scrutiny, I'm just happy java isn't C/C++.
Comment by carlmr 3 days ago
In some cases you want "default" handling, in other cases it's a runtime detection of a code issue. E.g. you could add a "fallback" case which is the same as "default" yet if your code doesn't exhaustively handle all sealed class cases won't compile. This would still create a fallback, if your sealed class is widened later on, but still allow you to error out if it's already the case right now.
Comment by masklinn 3 days ago
That is a false dichotomy. Some enumerations have reasons to likely change in the future, others (most) either have no such thing or their changing would be so impactful to the system it needs to be signaled loudly.
That’s really no different than any other type information.
> It's always a tradeoff and you can also always fork or propose your own improved version of the concept
You are the person asserting that the concept as defined is incorrect.
Comment by rf15 3 days ago
Comment by nmadden 3 days ago
[1]: https://marc.info/?l=openjdk-security-dev&m=177435495515512&...
Comment by shepherdjerred 3 days ago
With the said, you can do exhaustive pattern matching in TypeScript! https://github.com/gvergnaud/ts-pattern
Comment by ngruhn 3 days ago
function exhaustive(witness: never): never {
return witness
}
https://www.typescriptlang.org/play/?#code/FAFwngDgpgBAKgZQB...Comment by ddosmax556 3 days ago
default:
matched satisfies never
throw new Error(...)
You don't even need a function.Comment by whilenot-dev 3 days ago
[0]: https://docs.python.org/3/library/typing.html#typing.assert_...
Comment by n_e 3 days ago
Comment by AdieuToLogic 3 days ago
If you perfer using the same language for both frontend and backend work, yet would like to have one more semantically rich than TypeScript, consider Scala.
For the frontend, ScalaJS[0].
For the backend, Scala[1].
Comment by theanonymousone 3 days ago
Comment by wk_end 3 days ago
https://www.typescriptlang.org/play/?jsx=4#code/JYWwDg9gTgLg...
I guess the library is slightly nicer, arguably, but I don't think it's worth the external dependency and added complexity.
Comment by pjmlp 3 days ago
On the other hand, at least I get an excuse to write native addons.
If it wasn't for the projects that require Next.js I would never bother with Node.
Comment by shepherdjerred 3 days ago
Yes, you can do it via an assert never in a switch. That isn't pattern matching. That's an exhaustive switch enforced at compile time
Which is nice, but again, it's not pattern matching.
Comment by DimmieMan 3 days ago
The sealed keyword makes sense, isn't unique to this feature and you can pattern match exhaustively. I feel like I could explain this to a beginner without overloading them, it's still 'just Java' while giving you a way to occasionally model a one-of relations with out the awkward default handling while sticking to the predominately OOP driven nature of the language.
The stuff you can do with a functional language is amazing but I don't think bolting on new paradigm's until you have a diabetic Frankenstein of a language is the right answer, Scalar is right over there if that's your preferred style.
Comment by misja111 3 days ago
I think this is quite bad. I think such a change should break binary compatibility between the consumer and the producer api jar. Now any consumer might or might not run into runtime errors when switching to a new producer jar that is binary compatible.
Comment by Good4boothee 3 days ago
Comment by looperhacks 3 days ago
However, it doesn't change the behavior much: LinkageErrors can also happen any time at runtime, not necessarily during startup. Just like the MatchException.
Comment by tpxl 3 days ago
Comment by nmadden 3 days ago
Comment by armchairhacker 3 days ago
Comment by smarks 2 days ago
[1]: https://news.ycombinator.com/item?id=50148756
The discussions around the PEM Encodings API also led my colleagues on the langtools team to write an article "Preparing for Change: Safe Switching over Sealed APIs" that discusses these issues in more detail. [2]
[2]: https://openjdk.org/projects/amber/guides/exhaustiveness-gui...
The article focuses on pattern matching and exhaustive checking, because this is an important feature for a large class of applications.
As a library designer, though, I'm primarily interested in the use of sealed classes to control subclassing. The old idiom for controlling subclassing of concrete and abstract classes was to ensure that all constructors had package access or less. This mostly prohibits subclasses outside the package. (Strictly speaking, it prohibits such subclasses from being compiled or instantiated.) For interfaces, it was formerly impossible to control subclassing at all. The addition of sealed classes to the language solves the problem completely.
Indeed, in the JDK we've converted all the uses of the older idioms to use sealed classes. [3] (This bug covers most of the changes; there are a handful of others that were converted individually.) Of the several dozen examples here, it doesn't look to me like ANY of them are candidates for pattern matching. This probably reflects the long-standing issue of subclassing control in object-oriented systems. That issue has existed in Java much longer than pattern matching. As time goes on, I expect the JDK class libraries to introduce more new APIs that make use of pattern matching and sealed classes.
Comment by timshel2 3 days ago
Comment by hibikir 3 days ago
Comment by mlinksva 3 days ago
Comment by cryptos 3 days ago
Comment by AdrenalinMd 3 days ago
It's like French poetry.. So much elegance. An no effect system BS. Just like Martin Odersky intended it to be!
Comment by theanonymousone 3 days ago
Yes, but also a bit of a torture to read code in it..
Comment by owlstuffing 3 days ago
Too far: there are several dialects one can use with it e.g., I can speak Haskell with Scala grammar. Unlike with Java there is no central Scala dialect, so reading/maintaining a Scala codebase can be a challenge.
Too close: its type system, as advanced as it is, is still stuck in Java’s inheritance and all its limitations. Traits, for example, are not runtime components, they dissolve into the hosting class’ single object, giving up the independent identity and flexibility of runtime configured composition. And the Scala 3 `exports` feature that departs Java’s inheritance is just forwarding, not true delegation; it is the inverse of traits: it trades self identity for independent identity (no late-bound self that comes free with impl inheritance).
Comment by rhdunn 3 days ago
I prefer extension methods for what Scala implicits do [1], [2]. The only part that is lacking with extension methods is to be able to extend a type to implement an interface, e.g. Comparable, but you can create extension methods that return anonymous objects [3].
[1] https://kotlinlang.org/docs/extensions.html#anonymous-extens...
[2] https://learn.microsoft.com/en-us/dotnet/csharp/programming-...
[3] https://discuss.kotlinlang.org/t/extensions-function-to-impl...
Comment by gf000 3 days ago
Comment by rr808 3 days ago
Comment by therealdrag0 3 days ago
Comment by tentacleuno 3 days ago
Comment by jmalicki 3 days ago
Comment by pdpi 3 days ago
Comment by troupo 3 days ago
Thankfully, not in the core language :)
Comment by ackfoobar 3 days ago
There are just too many ways to use Scala, and everyone thinks they're doing it "idiomatically".
Comment by dozerly 3 days ago
Comment by another_twist 3 days ago
Comment by panny 3 days ago
Comment by thfuran 3 days ago
Comment by BatchJob 2 days ago
Comment by favori995749721 3 days ago
Comment by ironqcold 3 days ago
Comment by curatedmcp 3 days ago
Comment by Larrikin 3 days ago
I didn't mind Java when the comparisons were to C++, Ruby, and Python. I can not find a reason to go back after Scala (which seemed to fail due to being indiscriminate) and especially Kotlin
Comment by pron 3 days ago
If you like a richer language, the Java platform offers you options, but many people prefer smaller languages (the number of Java Platform developers who use the Java language has remained pretty much at a constant ~90% for the past 15 or more years), but we're aware that a non-tiny minority of developers prefer richer languages, and so we accommodate them, too. Either way, 95% of the JDK is runtime (standard library and the JVM) and tooling, and you'll enjoy it regardless of which frontend language you prefer.
Comment by giamma 3 days ago
I have been working in product development for 25+ years, and I have friends in different organizations all over Italy, where I live. They told me many horror stories of clients who had custom software built by consultants using Scala because it was cool, and few years later the consultants disappeared and the client remained with a sophisticate piece of software that is crucial for their business, which was written in a language that no other consultant wants to touch.
In short, while there are better languages out there, Java is a decent language with a large developer base and from a long term perspective and from a risk management point of view, Java is still the best choice for me. The latest revision of the Tiobe index shows Java at fourth place while Kotlin and Scala rank respectively 32nd and 40th place.
Comment by haspok 3 days ago
...or maybe they are not willing to pay a high enough price for said consultants? I can guarantee you there would be many takers for the right price.
Some could say that the higher price is not justified, but that is a different discussion. Some others could also argue that if you pay peanuts, you get monkeys...
Comment by quietbritishjim 3 days ago
i.e. today's consultant is justified in charging that price, but yesterday's developer was not justified in using Scala which caused such high future maintenance costs.
Comment by gf000 3 days ago
Comment by bmacho 3 days ago
This strategy will still navigate Java into a random local optimum like it happened with other languages (that value backward compatibility), just more slowly. The greedy algorithm does that. Even if you do it slowly and you are extra careful that each step indeed betters the language.
Comment by pron 3 days ago
But if in 2026 Java is the third or second most popular language in the world overall and the #1 choice for large applications that are performance-sensitive and/or need to be maintainable, but is it possible that in 20 years, despite our best efforts, Java will decline sharply, perhaps even to the point of being only as popular as, say, Go is today? Sure.
Comment by valzam 3 days ago
Comment by oldsecondhand 3 days ago
Comment by throwaway7783 3 days ago
Comment by fallingbananna 3 days ago
Compared to Scala, C++, or even Typescript and C#, Kotlin feels a like a well thought out minimal modern language (as minimal as you can be, while still providing conviniences that we have grown to expect like nullability checks, or data classes).
(*Except coroutines, I feel like Java is achieving that goal waaay better with virtual threads and structured concurrency than Kotlin did with "forever experimental" API that is full of footguns and lacks any observability.)
Comment by gf000 3 days ago
Funnily enough kotlin added some rushed, delivered syntax sugar in the form of `when` and java just came and added proper pattern matching with algebraic data types and exhaustiveness checking into the platform itself, making it better than the guest language at its own game. Meanwhile I never felt this "landing page growing" mindset with Scala.
Comment by pjmlp 3 days ago
C vs C++ vs Objective-C on UNIX systems, JavaScript vs Typescript (hence why they now focus on it as a linter and nothing else), ...
Comment by derriz 3 days ago
Comment by speed_spread 3 days ago
Comment by CrimsonRain 3 days ago
I know it is not a technically marvelous thing, it's not a high priority either...but the only thing I'd want differently is lot more syntactic sugar that reduces common boilerplates/actions/patterns to simple one liners.
However, with AI writing most of the code now, I now doubt the importance.
Comment by dtech 3 days ago
This seems disingenuous at best, or it's a symptom that I've noticed as a user more often that your JDK team seems to have blinders on and dismisses/ignores most other languages even if feature have proven themselves 10 times over.
There's several features Java added or is trying to add, usually 5-10+ years later than Kotlin, and that's ignoring Scala:
* Local type inference
* Switch expressions
* Records, although I found them barely usable because there is no copy() method or with-ers
* String templates unsuccessfully
* A very stripped down version of smart-casting with switch pattern matching
I'm sure there's tech-debt and esoteric compatibility concerns which make evolving Java hard, but from a developer's perspective it's just glacial to evolve and the result is weaksauce.
Comment by pron 3 days ago
BTW, even if you're not aware of ML's extraordinary influence on most programming languages, surely you're aware there are competitors to Java with analogous features that are far bigger than Kotlin.
As for string templates, our intent is not to have a feature simiar to what Kotlin offers. We obviously look at all languages regardless of popularity, but in that case, as we did in the case of virtual threads or records, we'll probably say, no, that's not what we want, to Kotlin's approach (even the Preview that we pulled was nothing like Kotlin's approach).
> I'm sure there's tech-debt and esoteric compatibility concerns which make evolving Java hard
Backward compatibility is rarely a hindrance at all. People just talk about it a lot because most organisations consistently say that backward compatibility is much more important to them than any language feature, but it's not all that hard to maintain.
> but from a developer's perspective it's just glacial to evolve and the result is weaksauce.
I find that statement hard to reconcile with the fact that the only languages as popular as Java or more are JS/TS and Python, while all the languages that are not "weaksauce" from "a developer's perspective" are doing far, far worse than Java. There has never, ever, been any sort of consensus among developers on the right set of features, and there have always been developers who prefer more features and those who prefer less. It's perfectly fine to be on one side or the other or even to say, "yes, I'm in the minority, but I still think I'm right", but I find it strange to claim to represent "the developer's perspective" when your preferences are mostly associated with languages that are doing worse rather than better.
Comment by tialaramex 3 days ago
There are definitely many programmers who have a very parochial understanding of programming. They know one or two languages well, they've never been interested in what else might be possible - maybe they never took a language survey course or they barely paid attention in that class - and so they genuinely do not know what else is possible or what might be normal in other languages. This happens to spoken languages too, in English "singular they" was already right there ready to be used for cases where we do not want to specify gender, in some languages there was never an issue here, gender was only ever an optional adjunct so just don't specify if you don't want to, while in others a default gender is so engrained into the language that you're basically fighting the assumption just to say a simple sentence. But if you only know English there's no reason you'd realise that varies.
Comment by matsemann 3 days ago
Mind you, I like that java has taken its time to get the features right. Of course, java has had the advantage of enhancing the jvm while adding the features, where Kotlin had to work around the jvm in some cases (like green threads vs coroutines).
So I prefer javas version of many of the of the more modern things (but do miss Kotlin's lambdas and vast library of extension functions when writing java). But I feel it's wrong to downplay Kotlin's role in modernizing things on the jvm. Heck, if it weren't for kotlin as a temporary stopgap, I'd probably would've left the jvm while the features were still lacking in java.
Comment by pron 3 days ago
I disagree for an obvious reason: only a small minority of Java developers know Kotlin. When we want to see if the median developer is ready for some ML feature, we certainly look at other languages, but Kotlin doesn't matter beyond its size (which is not inconsiderable, but is also nowhere near the largest Java competitor that's quick to adopt features).
> Of course, java has had the advantage of enhancing the jvm while adding the features, where Kotlin had to work around the jvm in some cases (like green threads vs coroutines).
And C# could have done the same as Java but instead did what Kotlin did (or, rather, Kotlin did what C# had done), and we looked at both and said: we don't want that. That's why I'm saying that the "catching up" narrative doesn't hold up to any scrutiny.
Obviously, Java has been a huge innovator in optimising compilers, garbage collection, and low-overhead telemetry — areas where it's ahead of virtually everyone else — and focusing innovation on the runtime rather than the language has been one of James Gosling's stated goals since the beginning. So catching up is also silly when talking about a technological leader.
> But I feel it's wrong to downplay Kotlin's role in modernizing things on the jvm.
I'm neither downplaying nor overplaying it. As one of the Java architects, I'm telling you what it is. And "modernising things" on the Java Platform ecosystem is quite a different thing from influencing Java language features.
When we discuss other languages, and we discuss all of them, the ones that are discussed more are either the bigger ones or the more novel ones. Kotlin has shown some novelty, especially around its design of generics and of nullability types, but these happen to be two areas where we have actually not (yet?) made changes.
> Heck, if it weren't for kotlin as a temporary stopgap, I'd probably would've left the jvm while the features were still lacking in java.
That may be true, but it's irrelevant to what we're discussing. If anything, if Kotlin had served as a significant enough stopgap for those developers who prefer richer languages, it would have helped us not to adopt certain features or to adopt them more slowly.
I'm not saying Kotlin hasn't had a positive influence on the platform and, indeed, it may have helped especially in those years when Java stagnated, but it didn't push Java toward adopting more ML features.
Comment by brabel 3 days ago
This is just so wrong. I don't know a single Java developer who does not know Kotlin. In fact, almost everyone is using Kotlin for most code, with Java being mostly used in legacy projects.
I know you'll answer that I am in a bubble or whatever, but it's frustrating how you think that's a valid argument you can make against me, but not me against you :D seriously. You have no idea what my experience is. I've worked in several countries so I can tell you my experience is not just local. I still like Java (and with Java 28 I am becoming hesitant to continue using only Kotlin for new projects) but anyone who cares about new features like pattern matching was already on Kotlin a long time ago.
Comment by pron 3 days ago
> but anyone who cares about new features like pattern matching was already on Kotlin a long time ago.
First, that doesn't mean it's not a minority of people. And by the way, we don't base our decision on which language feature to include on the number of people who are already asking for a feature (which is always a small minority) but on the number of people we believe will be significantly helped by a feature once they learn about it. I.e. it is perfectly possible that 100% of the people who wanted pattern matching before we added it had left for Kotlin or Scala and at the same time that number amounts to only 10% of the people who enjoy the feature and benefit from it in Java. That many mainstream languages add a feature is only a signal to us that the median developer is ready for it if we decide it's a good feature to add. I've been using pattern matching since the late nineties when I first learnt ML and a bit of Haskell (Haskell was the language of the future back then), but if I were a language designer back then, I'm not sure I would have thought that it's a feature a mainstream language should have prioritised in 1998.
Second, we don't have usage telemetry in the JDK so we don't get a full picture, and instead we rely on the usual sources for this kind of information: meeting with large customers and analyst reports. If you have access to more comprehensive statistical data, then I would be interested in seeing it, but it's a well-known phenomenon that people are usually only directly exposed to information about their own circles and don't have industry-wide data. The Java ecosystem is huge, and like the situation with the software industry in general and enterprise software in particular, most Java software isn't even written by software companies.
Comment by matsemann 3 days ago
https://www.jetbrains.com/lp/devecosystem-2022/
Which matches what I've seen. Every single huge company or government function in Norway have the last years written most of the new code in their applications in kotlin. Basically all java conference talks I've seen has kotlin as the backdrop.
Kotlin's impact in preparing java devs for more functional code has been tremendous.
Comment by pjmlp 3 days ago
Also JetBrains is the creator of Kotlin, naturally they want to show their baby is being adopted.
Comment by speed_spread 3 days ago
Also, rest assured that there is still plenty of corporate drones that don't know Kotlin and couldn't care less because Java puts food on the table while providing a stable consensual development environment. Kotlin opens many doors, most of which should have better be left closed.
Comment by matsemann 3 days ago
Comment by speed_spread 3 days ago
And it pisses me off even more that my tooling provider is the party actually building and promoting this substandard replacement and that I can't boycott them because the other IDEs are either legacy clusterfucks (eclipse) or glorified local websites (vscode).
As much as I try to keep my composure on HN and stay constructive in my contributions, I don't know how to help derail this particular train.
Comment by brabel 1 day ago
Comment by mh0s41n 3 days ago
Comment by throwaway7783 3 days ago
This used to be the case a few years ago. But not anymore. Java is evolving very rapidly compared to those years.
Comment by troupo 3 days ago
A few years back the same argument was phrased as "we don't adopt features from lesser languages" or something to that effect. Since then Java has been busy adopting those features at an accelerated pace.
> If you like a richer language, the Java platform offers you options, but many people prefer smaller languages
And Java is no longer a smaller language. Because artificial purity for misguided reasons hurts the language. And thankfully most people in Java have finally realized it.
Comment by pron 3 days ago
Except it wasn't, because adopting ML features, especially lambdas and generics, were discussed in the Java team even before Java was released.
Also, the "accelerated pace" is only compared to a dry spell where development stagnated not by choice but by Sun's problems. We had a pace we liked, then we were forced to slow down, and now we're back to the pace we like again.
Also, it has always been a stated strategy to focus on innovation more in the runtime than in the language (Gosling called it "a wolf in sheep's clothing"). Java has always aimed to innovate in compiler technology, garbage collection, and telemetry as fast as it could, and we innovate faster than most in these areas.
> And Java is no longer a smaller language.
No longer smaller than what? We aim to keep the language relatively small, i.e. smaller than mainstream languages that are more eager to add features. So Java is bigger than Go, but it's smaller than C# or Kotlin or Rust, and is roughly comparable to TS or Swift in its "size".
Comment by troupo 3 days ago
Except it was. It was you saying this. [1]
And yes, those ML features, and many other features, were adopted by other languages, and faster, than Java. Now you're suddenly saying "we're aware that a non-tiny minority of developers prefer richer languages, and so we accommodate them, too" and "oh yes, we've been thinking of these features since 1991".
> No longer smaller than what?
Than whatever your ever-changing definition is. Java, thankfully, is no longer a small/smaller language, and is rapidly adopting actual useful features, including those from lesser products.
Unfortunately it may be held back by people still thinking that a language should not be useful in any way, shape or form. Thankfully, you're being dragged into modern world kicking and screaming. Maybe in 10 more years Java will catch up with the rest of the world (as I said, it's been catching up quite rapidly).
---
[1] https://news.ycombinator.com/item?id=28985688
"our goal isn't to adopt the strategy of less successful products, but to forge our own"
Comment by pron 3 days ago
I said "strategy" not "feature". That adopting a feature that a less successful language had invented or adopted is not the same as adopting the strategy of a less successful language was precisely my point about buying a sofa not being the same as "catching up" to a hoarder.
I said "we shouldn't be a hoarder", not "we shouldn't get a sofa".
> Now you're suddenly saying "we're aware that a non-tiny minority of developers prefer richer languages, and so we accommodate them, too" and "oh yes, we've been thinking of these features since 1991".
But Java started adopting ML features over twenty years ago. Where do you think we got generics from? The discussion about lambdas and generics between Gosling and Joy, even predating Java's release are Java lore (https://archive.computerhistory.org/resources/access/text/20...).
> Than whatever your ever-changing definition is. Java, thankfully, is no longer a small/smaller language, and is rapidly adopting actual useful features, including those from lesser products.
My definition isn't ever-changing, it's just relative. Being a relatively small language means, at the same time, not adopting the strategy of richer languages and adding select features but at a slower pace. This was Gosling's "a wolf in sheep's clothing" strategy since the very start: a very innovative, fast-moving runtime (where most of the benefits to the software's end user are hidden) wrapped in a non-threatening, conservative language. Conservative doesn't mean frozen and relatively small doesn't mean never-growing, but they do mean not adopting relatively rich fast-changing language strategy either. Our strategy has worked well for us, and yes, I still think it's silly to suggest we should change it because languages that aren't doing as well have a different strategy.
Even Java's GC and JIT came from Lisp and Smalltalk, but not the strategy (which was Gosling's point that these helpful features were part of thretening products).
Comment by troupo 3 days ago
Strange. Every time we talk about features and what other languages have, you always come up with "lesser languages" and "hoarders".
When Java ends up adopting those features, suddenly it's "we accommodate a non-minority number of developers" and "we've been thinking about this since before Java was released".
> My definition isn't ever-changing, it's just relative.
Yup.
> illy to suggest we should change it because languages that aren't doing as well have a different strategy.
...aaand there it is again. "The lesser languages".
Anyway. I'm glad it seems you're in the minority seeing how Java has picked up its development pace. Hopefully it will only accelerate and adopt more features for "non-minority number of developers we've been thinking since before 1991".
Adieu.
Comment by pron 3 days ago
It's not those features, though! Obviously, a hoarder has everything, so anything you buy is something he has. We are adopting a small portion of the features that feature-rich languages have, which is exactly the difference between a more feature-rich language and a more minimal one.
> ...aaand there it is again. "The lesser languages".
Again? I haven't said "the lesser language" once, although you've now said it a few times as if quoting me. You're arguing with things I haven't said and then misquote me to completely change the meaning of what I actually wrote.
No one, on the Java team or outside it, considers Lisp, Smalltalk, and ML - the languages that inspired Java - "lesser" languages. They are, however, all less successful languages as a matter of fact. It is because they are not lesser but they are less successful that we selectively adopt a portion of their ideas but do not adopt their strategy.
It's not about snobbery, but basic business strategy. Suggesting that it's good business for a product to adopt the strategy of some competitor product doesn't make much sense when that other product is doing worse than your own. I mean, maybe it could be interesting if there were some other key element to the plan, but not on its own.
Almost every single feature in Java was inspired by (or sometimes copied from) a feature in a less successful language (although not always less successful at the time the feature was adopted), but Gosling was always very clear about copying good ideas into a product with a very different strategy (he thought it was the strategy that hindered those other products, not their ideas).
> When Java ends up adopting those features, suddenly it's "we accommodate a non-minority number of developers" and "we've been thinking about this since before Java was released".
No, we've also been thinking about features that may well probably never make it. I'm not even sure what you're trying to say, but you should know that anyone who works in language design has been familiar with type inference, generics, typed lambdas, pattern matching, and algebraic data types at least since the late eighties because ML has been the biggest single influence on language designers and other PL fans in the past couple of decades (ML was released in the early seventies, but it didn't become so influential right away).
> I'm glad it seems you're in the minority seeing how Java has picked up its development pace.
Java has picked up its development pace compared to the time we were involuntarily stagnant due to declining investment from our corporate overlords. As always, most of the development is in the runtime, as that has always been our strategy, and we all think it's a good one. I'm very happy that we can do more now than we could fifteen years ago, but the Java language won't become a (relatively) feature-rich language, even though it will continue to add features.
Comment by DarkNova6 3 days ago
I can't help but to be a little sobered by the promises of Kotlin and C#. They look great on the surface, but once you have more complicated code to work on they tend to show warts quite fast.
Java is remarkably consistent and really doesn't have any sharp edges. Even with generics and type erasure, I found myself fighting the language semantics in C# way more often than Java.
Comment by cogman10 3 days ago
That said, Java taking it's time and observing the playing field is a huge benefit. And now that they've been slowly delivering new language features, it's really made it pretty nice flow of powerful well thought out extensions each release. There hasn't been one of the new features that I think missed the mark.
Comment by jayd16 3 days ago
What's an example? I find C# quite well designed despite the Chinese menu of features.
> Java is remarkably consistent and really doesn't have any sharp edges. Even with generics and type erasure [...]
These back to back with a straight face...What is a sharp edge in your mind?
Comment by arein3 3 days ago
Saw that in a typescript repository
It's ok when it's part of a very specific library, it's not ok using it as part of usual project code
Comment by jayd16 3 days ago
Comment by ysleepy 3 days ago
Comment by afdbcreid 3 days ago
Like in Java? C# has its own sharp edges (like most or all languages), but it's almost disingenuous to bring a feature that is much more complex and weird in Java as an example.
Comment by biglyburrito 3 days ago
Comment by za3faran 3 days ago
Comment by peterashford 3 days ago
Comment by jmarlow47 3 days ago
Maybe Roman really was the soul and it lost its touch without him?
I guess in the age of AI it doesn't matter since a few years from now, if you change your mind, you can just ask Jeeves to one-shot rewrite it back to Java.
Comment by jeroenhd 3 days ago
I can speak from experience that Fable 5.1 still writes code that compiles and usually runs fine but throws null pointer exceptions in reasonable edge cases.
Comment by jmarlow47 3 days ago
That's probably the largest gap in usability.
Comment by arein3 3 days ago
Kotlin's implementation is very good, hoping with all my heart java will copy it
Comment by jeroenhd 3 days ago
Types would be nullable (default), explicitly nullable (new), and explicitly non-nullable. Concretely, something is nullable, nullable, or non-nullable.
"Nullness is ignored when determining whether two methods have the same signature" is also rather annoying, this takes away the ability to provide fast overloads for non-null types for instance. Feels like a missed opportunity to me, though I'm sure there are reasons for that.
Comment by vips7L 3 days ago
Comment by biglyburrito 3 days ago
Comment by pjmlp 3 days ago
Also who cares having to use String.format() in the agentic coding age?
Comment by kbenson 3 days ago
Comment by ndriscoll 3 days ago
Comment by kbenson 3 days ago
It's the trivial cases that are compile time. The interesting templating is done with input that isn't defined within the source, and those can't be run entirely at compile time.
> And you automatically get things like safe SQL queries with parameter binding instead of injection vulnerabilities.
That's been solved for decades with parameterized queries (binding variables), and doesn't require interpolation in any way (at least not in the context we're using it here, but probably not at all in most DB drivers and engines). In fact, I would go so far as to say if someone is trying to use string interpolation instead of parameterized queries to avoid SQL injection, they've fundamentally misunderstood the problem and are trying to solve it at the wrong layer.
Also, if the string interpolation for the query is done at compile time, what type of content known at compile time is something that we'd be worried about SQL injection being in?
Comment by ndriscoll 3 days ago
SQL doesn't require interpolation, but it's much cleaner to write it that way and not have to explicitly do binding. It's not an "instead." Like I said, what the interpolator does is automatic safe binding with interpolation syntax.
The content known at compile time is the query template that you're binding. The point is a compile-time interpolator turns e.g. `sql"""select * from users where name=$name"""` into `Statement("select * from users where name=?").bind(name)`.
You can also have macro fragments as "inline def" functions in e.g. Scala so that they compose naturally. c.f. Quill[0].
Comment by MiroslavPokorny 3 days ago
Comment by ndriscoll 3 days ago
The thing that tends to be expensive for compilation, at least in Scala, is automatic recursive typeclass instance derivation. And even that one can be mitigated by just manually writing e.g. `implicit val jsonDecoder = JsonDecoder.derive[MyClass]` for each class. Otherwise compilation isn't an issue IME. Again, the time saved being able to work in "if it compiles, it works" mode easily dwarfs the time spent compiling.
Comment by MiroslavPokorny 2 days ago
Comment by kbolino 3 days ago
Comment by whartung 3 days ago
And clearly a lot of work and time went into it with the previews.
The fact that they pulled it back suggests they looked down deep into an abyss that looked back at them, and what they saw scared them.
I don't know if there has been a published deep dive post mortem on the whole string templating thing, but I am quite comfortable with the team yanking it out if they felt it wasn't right.
Comment by pjmlp 3 days ago
Maybe there is something on the mailing lists.
Comment by mystifyingpoi 3 days ago
Comment by ndriscoll 3 days ago
Comment by pjmlp 3 days ago
Comment by hibikir 3 days ago
It's a very conservative language that wants to minimize breakage, and the tradeoff is not without costs. I would argue than in LLM-world, the right tradeoffs change, but I don't think a language like Java is going to assume everyone has an LLM to do migrations for free any time soon.
Comment by sthuck 3 days ago
If you put a gun to my head and tell me you can't write in kotlin, you must choose either Java or Scala - for a small project I think I choose modern Java. If you tell me I need to choose for a large cross team and mission critical project - I think I take the bullet.
Still, I have a soft spot in my heart for scala, learned a lot from it.
Comment by hibikir 3 days ago
Comment by blandflakes 3 days ago
Comment by misja111 3 days ago
Comment by cryptos 3 days ago
Comment by sideeffffect 3 days ago
Does it, really? Java has had pattern matching since 21 (2023). Kotlin still, to this day, the year of our Lord 2026, doesn't...
Comment by tancop 3 days ago
Comment by za3faran 3 days ago
Comment by ackfoobar 3 days ago
Comment by wiseowise 3 days ago
Comment by sideeffffect 3 days ago
Comment by dtech 3 days ago
Comment by sideeffffect 3 days ago
Comment by 14u2c 3 days ago
Comment by Sharlin 3 days ago
Comment by pjmlp 3 days ago
Without Google's godfather, Kotlin would be gone for now.
Kotlin is so great, where is the Kotlin Virtual Machine, showing how Kotlin can stand on its own?
Comment by jayd16 3 days ago
Comment by dathanb82 3 days ago
Comment by jayd16 3 days ago
Comment by dathanb82 3 days ago
Comment by jayd16 3 days ago
I mean, I don't really care about any of that. I was just responding to the (likely unserious) technical critique that there is no Kotlin VM. As for whether Kotlin as a language would be popular without the JVM, that's a different question.
Comment by pjmlp 3 days ago
Comment by pjmlp 3 days ago
It is so good, that JetBrains themselves rather use Rust or C++ for native code libraries on their IDEs, and not officially supported on the Android NDK.
Comment by jayd16 3 days ago
Comment by pjmlp 3 days ago
A sign of maturity that Kotlin is grown enough to leave its parents foster home, and stand on its own without pay checks from its folks.
Comment by oldsecondhand 3 days ago
Comment by vips7L 3 days ago
Comment by pjmlp 3 days ago
Kotlin Native came later, its memory model was incompatible with Java, thus breaking portability for libraries between JVM and Kotlin Native, thus Jet Brains had to reboot Kotlin Native memory model.
https://blog.jetbrains.com/kotlin/2021/05/kotlin-native-memo...
Currently it is mostly used to port Android code into iOS apps, hardly something that even JetBrains could show off running their IDEs on top off, nah, they still need the JVM.
Comment by troupo 3 days ago
With many others it doesn't compete because it would need a from-scratch rewrite of the runtime (Erlang/Elixir), or a from-scratch redesign of the type system (Rust, perhaps Swift).
Comment by pixelstack 3 days ago