4 ms·
What's wrong with java generics: erasure. "Cast everywhere" is still happening. And useful info is hidden: eg there is no access to generic type info via reflec
by crux_ 16y ago
What's wrong with java generics: erasure. "Cast everywhere" is still happening. And useful info is hidden: eg there is no access to generic type info via reflection. Another wrong thing: generics are incompatible with subtyping. (No co/contra-variance, to use the pointy headed terms)
Tail call optimization is not a mere optimization. A jvm cannot provide it and still provide conforming exception stack traces, for example.
As far as closures: you're missing out :)
- dantheman 16y agoAlso tail call optimization changes the semantics of the language - it allows you to write code that would normally be incorrect
- crux_ 16y agoTrue, although you have to be careful about "incorrect": the code will still compile (unless there's some corner case I'm missing?), so for that particular definition of correctness it is just fine without TCO. It just won't run (for very long). :)
- dantheman 16y agoI agree, but compilation is a low barrier for correctness :)
- sukuriant 16y agoWould it be that impossible to keep a counter of what iteration of function X the user is on? Or, does tail recursion also count things like: int A() { return 1 + B(); } int B() { return 1 + A(); } (with necessary ending conditions)
- crux_ 16y agoYes, tail call optimizations include mutually recursive functions. Note that your example was not of tail calls, however. (Tail call would be: return A(...); that is, a tail call is one whose result is immediately returned.)
- sukuriant 16y agoThat does become harder to follow, then. And, woops...
- mkross 16y agoWait, generics support co/contra variance through the 'extends' and 'super' keywords. e.g. Collection<? extends Foo>
- crux_ 16y agoI suppose so; but not in the sense I was thinking of: a Collection<Firetruck> is not a subclass of Collection<IVehicle> (and it is impossible for you to create your own generic class where this type of relationship would be true).
- mkross 16y agoWhile Collection<Firetruck> has an indeterminate relationship with Collection<IVehicle>, this is good! If Collection<String> was a subclass of Collection<Object>, you could fill the collection with Strings and then pass it off to someone who is using it for Objects and adds in his own Integer. Now your collection is borked. :( If you find yourself wanting to pass in Collection<Firetruck> to a method that only accepts Collection<IVehicle>, this usually means that the method isn't correctly typed. The rule of thumb for using 'super' and 'extends' is "Producer extends, Consumer super" or PECS. By applying this, the typing problem should go away, as your method is now accepting Collection<T extends IVehicle> and possibly returning Collection<? super T>, so you can both pass in your Collection<Firetruck> and reassign to a different variable of type Collection<Firetruck>. :) (I think Josh Bloch wrote up a decent blog post about the PECS principle a couple of years ago. It might be worth reading for more information.)
- crux_ 16y agoAs I enjoy the benefits of immutable data structures and read-only interfaces, it is absolutely not an unmitigated good. Replace "Collection" with "Iterator" above, and the borking you mention is impossible ...