Is it in the realm of possibilities that Java will someday have runtime generics support (instead of type erasure)? It's the most frustrating aspect of the language because you can't use basic Java features like method overloading with them. Also, I don't understand how people use the `Optional
<ErasedType>`..? Is there a way to use method overloading with it? `ErasedType` could be _anything_ at runtime, doesn't sound fun. Besides all references types are already nullable/(optional)...
so what's the point?
> Also, I don't understand how people use the `Optional <ErasedType>`..?
I may be misunderstanding your question, but in general you wouldn't be doing anything type-specific with an Optional's value unless you were in a part of your code that knows the type at compile time. For example, a data structure might return an Optional<T> from a get() method, but all it's doing is returning the T or an empty.
> Besides all references types are already nullable/(optional)... so what's the point?
1. It's nice to explicitly say if a value might not exist than to be unsure if a null object is meaningful.
2. It can force consumers of an Optional to deal with the empty case (versus forgetting to null check)
3. Null might mean something like "this value was accidentally never initialized" versus "I am explicitly indicating an empty value"
4. It can give better developer ergonomics with convenience methods or monadic style (such as with Scala's Option type, where you could .map() on an Option, or merge multiple Options together)
When exactly would you benefit from overloading based on a generic type? How come it is never brought up with Haskell for example, or the other majority of languages that employ type erasure?
You might want to have something like `String concatenate(List<String> strings)` and `List<T> concatenate(List<List<T>> lists)`.
Java won't let you do this because types are erased at compile time, and Java doesn't know exactly what function it's going to call until run time (in order to allow dynamically loading classes). Haskell does allow something similar to this kind of overloading, because Haskell determines what function is going to be called at compile time, before type erasure happens.
With checker framework, you can basically have it (and much much more, I believe no other language comes close to that level of static analysis). It is annotation-based and not a fancy keyword, but it is there.
Higher kinded types do make some features obsolete, but checker has MapKey checker, Lock and Index checker, and while locks may not be needed that often with everything is immutable by default mode, concurrency is hard and that alone is not always enough. While index errors are not as frequent in Haskell, due to (Head:Tail), but if you do use Array, you can’t express indexing safely without dependent types.
I’m not saying that it is better in every aspect than haskell (not too familiar with ocaml), but java is an easy and extremely popular language. And thus it has really really great tooling, and with annotations it is really extensible.
And if static analysis is not enough, there is also JML.
Also, checker taps more into intersection types, which is not really expressible in Haskell, but I’m yet again not knowledgeable enough on this latter, correct me if I’m wrong.