begin quoting Christopher Smith as of Sun, Jun 10, 2007 at 05:51:22PM -0700:
> Stewart Stremler wrote:
[snip]
> >No, it's because when you read up on Generics, you get an explanation
> >peppered with "you'd think X, but suprisingly, this isn't the case", and
> >then it goes off to provide a very logical reason why the language can't
> >do what you'd expect it to do.
>
> Type theory is sadly not taught to a lot of programmers, even though
> most programming languages are typed and a good chunk of them are
> statically typed. This tends to produce programs with errors that are
> very much like the ones that Java's Generics help address. ;-) That
Y'know, I rarely saw any of the errors that Java's Generics help
address, and never saw those errors in any unit-tested code. While
I'm sure that there are folks that *did* make those sorts of errors,
I'm also sure that those sorts of people will likely get bit by the
Generics gotchas as well.
> said, Java's Generics are *very* limited, and that does produce a number
> of disappointments when using them, but providing "limited" versions of
> things in an attempt to reduce complexity is a *very* Java thing, and a
> very *non*-C++ thing.
Sorry, I wasn't clear. It's not that it's the C++ feature set that's
creeping into Java, it's the C++ mindset that I'm whining about.
"Here's this clever, useful, but booby-trapped thing that's neat and
has a lot of smart people working on it. Let's put it in the language.
It'll be great!"
> >It's violating the principle of least suprise.
>
> I'm all for the principle of least surprise, but one of the catches with
> it is that what is surprising depends a lot on your context. In general,
> most of "surprises" with generics I've heard people complain about fall
> in to two categories: 1) things it can't do and 2) things it won't let
> you do, but if you'd did them without generics you'd have similarly
> disappointing results.
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".
I get really annoyed when I see those sort of phrases in explanations
of language features. I'd just as soon leave _out_ features if the
the feature's explanation has that sort of phrasing.
The categories you describe I wouldn't count as violations of the PoLS;
that's just garden variety whining, and counts as "blowing off steam".
:)
> >It's exactly like reading about many C++ features. At least to me.
>
> Honestly, on its worst day, Java Generics doesn't have half as many
> surprising gotchyas as C++.
Oh, indeed.
It's just that Java is heading down the C++ path, not that it's
suddenly transformed into C++.
[snip]
> >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.
> >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?
To make sure I'm not confused, this is what I understand...
Class B subclasses A, and Q subclasses P. i.e., A > B, P > Q.
A method foo() on A returns P. If B overrides foo(), and returns P,
then it's invariant. If the return type is Q, then it's a covariant
return type.
If, on the other hand, a method bar() on A returns Q, and if B overrides
bar(), and returns P, then it's a contravariant return type.
class P;
class Q extends P;
class A {
P foo();
Q bar();
}
class B extends A {
Q foo(); // covariant
P bar(); // contravariant
}
A contravariant return type seems very dangerous. If P is "Object"
and Q is "String", then it seems like a bad idea for a subclass to
return an Object instead of a String.
Return types seem like they should be covariant, and parameters should
be contravariant.
[snip]
> >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".
> Java Generics
> represents the better part of a decade's worth of work on the matter,
> not to mention all the other work that has gone on in the larger field.
Yup. It's very clever.
> 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.
Just like pointers... most of the time, they're Just Not Needed. And
when they are, there are workarounds that work well enough.
(And I've been told that in my C code, I'm pointer-happy.)
> >I don't want a one-language-fits-all-problems language. It just results
> >in a language that is equally unpleasant for all problems...
>
> Hmm... I think this was intended as a critique of C++, but it reads like
> a critique of Java. ;-)
Heh.
Java has a lot of warts. It's only a good language in comparison to some
other languages, and then only for certain categories of problems.
--
I do like the sandbox, even if the implemention is hellishly complicated.
Stewart Stremler
--
[email protected]
http://www.kernel-panic.org/cgi-bin/mailman/listinfo/kplug-lpsg