But what example would you have to demonstrate it's more powerful? As a matter of fact, Kotlin smart-cast approach can't tolerate mutability because it can't guarantee safety, yet Java guarantees.
Yes.. lol. The biggest argument now is Kotlin having nullness by default in the language. Just check around the comment section. Now java is planning to have them which will further help jvm to optimise for performance. Not sure what the next argument will be after.
Really? I don't thinks so. There is a reason JEP 539 is in preview. There is a reason internal annotations exists in current valhalla jdk prototype and upcoming java 28 such as @jdk.internal.vm.annotation.NullRestricted, @jdk.internal.value.ValueClass.newNullRestrictedNonAtomicArray. Also, there is a reason value classes are allowed to be null. This is because nullness types will be a key factor to the java language.
Also, future specialisation if it is introduced, it will enable the JIT to get enough information to ensure <T> becomes stored in cpu registeres or enable <T[]> to be flattened in memory.
Yeaaah. They are going to introduce approaches for the programmer to decide if tearability is allowed or not. Already there are internal annotations for fields and types to enable it that probably will become a language feature in future.
I've done some tests with current value classes in latest prototype with full optimisation through annotation. Apparently, everything was being compiled to assembly code with no gc calls. It seems this old school ideology of slow java is about to end in near future. I'm actually intrigued how it will compete with Rust which can't optimise code further while running, while JVM JIT has more info which it could aggressively further optimise, especially hot paths.
And I notice, people aren't aware more things are being planned for. For example, the carrier classes being proposed, they will separate state description with state representation and this is where value classes will shine syntactically.
But with null-restricted types, Integer! and int has no difference semantically and representation. They plan to introduce null-restricted types in future.
Java’s planned approach is more like typeclass-style interfaces than unrestricted operator overloading. Types opt into core-defined operator contracts, rather than every library inventing arbitrary meanings for symbols.
Damn. You're old school. Java’s answer is virtual threads, not async/await. The idea is that most server-side IO can stay in direct style enabling blocking-looking code, cheap virtual threads underneath. So you don’t split the whole codebase into sync vs async functions just to avoid blocking OS threads. CompletableFuture and reactive APIs still exist, but Loom reduces the need to use them as the default application model. You can now launch millions of virtual threads to do IO.
Notice you point out features that were easy to add during the beginning where there was no concern of backward compatibility? Now that java is porting value classes to mainline and we might have them soon, and planned operator overloading through type class, I believe java approach is making careful design choices that are semantically sound, rather than adding features that create edge cases such as boxing invariants in unions like C#.
Value types will be optionally null. What java will introduce to the tooling is narrowing of nullness types. Hence Foo! <: Foo? <: Foo. This will assist in enabling safe domains or scope in code that are null-restricted with ease. Hence we can model around such a type system rule.