Stewart Stremler wrote:
And I'm talking about the official explanations of Generics that say
stuff like "suprisingly this is not the case" and "you'd think that,
but you'd be wrong".
Yes, and in those cases there are two explanations that always show up: 1) the surprise is due to limitations of the implementation or 2) the surprise is due to the fact that programmer's intuitions are not informed from type theory.

Perhaps an example would help. The one I keep having to explain over and over again is this one:

public class DerivedClass extends BaseClass {
...
}

Vector<DerivedClass> foo = ....;
Vector<BaseClass> bar = foo; //no can do!

To a lot of programmers this is surprising, not intuitive, etc. But you know what? Letting it happen would result in some *truly* unintuitive behavior that is exactly the kind of mistake that programmers without an education in type theory make when they fuss around with the non-generics version of the above code.
Never bothered me. Bothered some of my collegues, but I figured that
if you're passing around raw collections, you're writing poor OO code
anyway, so why worry about it.
It's the having to wrapper your raw collections with the same stupid type checking logic that can be done far more consistently and correctly by computer. It's the having to put in type checking logic even when you can prove that it is totally unnecessary, etc.

Encapsulate -- this is OOP we're talking about, yes? -- and cast. Be
sure to write a bunch of unit tests. End of problem.
Yup, so now you write wrapper methods for all the methods you use in your collection, and then you write unit tests for all those methods.... you've now written a good dozen or more unit tests and burned through a good chunk of your day, and in the end you've accomplished less than what the computer can do for you in a fraction of a second. Furthermore, it is harder for someone to verify that you haven't messed up somewhere.
All I wanted was covariant return types.

But now I read that you're not supposed to use those... Wah!
covariant return types unfortunately can get you in to trouble. Contravariant are somewhat better, in that the nature of the trouble is somewhat better, but still.

Um, contravariant return types are better? How does that work?
http://www.icsi.berkeley.edu/~sather/faq.html#14

And for the record Java does have covariant return types (ever since JDK 1.5 IIRC). The disadvantage of covariance is that some errors can only be detected at runtime.
Had they put the thought they put into "synchronize" into generics, they
hopefully could have come up with something less obnoxious.  Or decided
that it wasn't important (like multiple inheritance).
They actually put a LOT of thought in to generics.

Well, sorta. It's the wrong sort of thought. It's all "how to make
this happen", not "is this really a good idea for Java".
Actually, there was a lot of thought of exactly that nature put in to it. Generics were very deliberately left out of the original implementation of Java and held back from subsequent releases until the powers that be thought they had a solution that was a good idea for Java.
The synchronization stuff is very weird though. I mean, what sane person really thinks that monitors are the *only* thing that would benefit from succinct, encapsulated, guaranteed lexical scoping.

It does the job well enough most of the time.
You misunderstand. The problem isn't with how Java manages its locks. It's with how it doesn't provide a similar mechanism for managing any other constrained resource.

--Chris

--
[email protected]
http://www.kernel-panic.org/cgi-bin/mailman/listinfo/kplug-lpsg

Reply via email to