After using Kotlin in Spring projects for a couple of years, I rewrote most of it to Java 17 and stick to Kotlin strictly in Android work. It's not that much different anymore with all the recent additions to Java, and as Java progresses (and the main JVM implementation which is first and foremost being developed for Java) and diverges in other directions in some very important areas (value types, Loom), Kotlin starts to feel more and more like a second-class citizen. I mean, that's what some old-timers were preaching right here on HN from the very start.
Things like Hibernate require some pretty ugly (IMHO) hacks to work properly (you need something like three compiler plugins, and spread keywords around like there's no tomorrow).
The compiler was also very slow compared to Java. The same amount of code written in the same style took 2× times to build. This may have improved.
Probably the only thing I miss are nullability annotations (after getting used to them in C#, not Kotlin).
Edit: after re-reading what I wrote, the tone feels way too critical. Kotlin is a nice language, and certainly easier & more fun to both read and write (although it's trivial to write unreadable mess by going too far with its features). It just doesn't go far enough (for me) to warrant using a separate language with all that entails.
You raise an interesting point: Maybe Kotlin was the push Java core devs needed to increase their rate of innovation ("release cadence"). I saw similar with Netscape vs IE, Chrome vs IE, Clang vs GCC, Boost vs C++ foundation library, .NET vs Java, Java+.NET vs C++, Node vs Deno. Kotlin can continue to experiment with new and interesting language features. Those that prove most popular can be adopted by Java. Also, as a secondary effect, since Jetbrains wrote Kotlin and had the best IDE, they had a head-start to build the community. That also helped to sell more IDE licenses. (I have nothing against this 1980s spy movie "master plan": They are great company with many great products.)
Java has adopted maybe 20% of the things that make Kotlin better, but due to backwards compatibility it'll never catch up.
Personally I think it'd almost never make sense to adopt Java over Kotlin for any greenfield JVM project, unless the devs you hire are truly so low-skill they can't pick it up.
> Java has adopted maybe 20% of the things that make Kotlin better, but due to backwards compatibility it'll never catch up.
Kotlin supports neither structural pattern matching nor guarded patterns as they are available in both Java 18 and Scala. It's Kotlin that needs catching up nowadays.
In Java 18, this is the pattern matching you're talking about.
`if (o instanceof String s) {`
Not much benefits over Kotlin's smart casts.
Guarded patterns with this version of pattern matching should be translatable to adding another "and" condition. The Kotlin compiler should have no problem reasoning with that.
---
I find positional destructuring in Scala (which works similarly in Java 19) a bad design.
What's the point of Kotlin, aside absence of semicolons and the 'val' keyword, if it plays the catch up game with the rest of the features becoming available first in Java?
> They can't have it instantly.
Why not if Scala did it way before pattern matching was introduced into Java?
Read-only interface by default - `MutableList` vs `List`.
if-expression, they just look nicer than `a ? b : c`.
---
You're right that Kotlin is not an "abstraction atop Java (the language)". It's meant to be a better Java that feels familar to Java. With that rationale in mind, it's reasonable that they left some features from FP languages out of Kotlin.
As I have said in another reply, it was a great decision to not follow what Scala did with pattern matching.
The gap has closed somewhat for sure, but there's still quite a few nice features in Kotlin that Java doesn't have. https://gist.github.com/makosblade/8fb1f577d81f02025784093d2... does a good job at identifying most. I'd add the semantics around lambdas are much nicer better in Kotlin.
With the passionate hatred both languages inspire, I'm not sure which is which in your statement.
One could argue C++ gets even more done, since it is appropriate for use in more contexts, like firmwares/drivers, native SDKs, games, etc. Java's main use cases have strong competition in languages like C#, Go, C++, Python, etc.