Hacker News new | ask | show | jobs
by _asummers 4083 days ago
It's not necessarily that people regularly see it as a problem, it's just that sometimes you get yourself put into a type corner and the lack of it causes you to have to repeat yourself. I'm not sure what the alternative world would look like, but I feel like this means the type system simply isn't expressive enough to cover this particular problem.

Upon thinking about it a bit, this problem seems to be functionally equivalent to pattern matching on the type of the message (which Java also lacks). I'm not a Haskell guy, but the immediate solution I'm seeing is to just have separate cases for each one. This is still an inferior solution in this particular case, because it forces you to modify the code in two places; luckily the type system helps here and makes sure you do.

But consider a problem of a different form:

Imagine I have an object Bar<S , T> and I want to have a frobnicate(S s) and a frobnicate(T t) method. Since Java erases, I can't do this. frobnicateS and frobnicateT it is! This is particularly annoying because you know S and T are different, but you can't express it to the type system! This seems like it'd be solvable by some sort of disjoint union, but again, Java lacks this. Fun fact, it does have a way to bind a generic on multiple classes: Bar<T extends Baz & Bat>. It would be natural to add a | for this sort of operation, if they ever figured out how to do this sort of operation.

2 comments

You can take advantage of lambda structural typing to work around the frobnicate overload issue http://benjiweber.co.uk/blog/2015/02/20/work-around-java-sam...

I don't think the same erasure problem is actually a consequence of type erasure - it is just defined in the spec.

I think generally the point is that "forgetting to a generic" is a dangerous operation because recovering that forgotten information is risky. It's inconvenient, but the alternatives are worse. Reflection, especially universally, blows up the amount you can trust your types very significantly.

Your Frobnicate example is interesting since you want an extra level of polymorphism in there, but getting this can be bad for inference (see MultiParamTypeClasses without functional dependencies). In any case, it's not clear why you ought to expect it to work.