Tuesday, January 22, 2008
As the closure debate flames are rising, people are attacking Generics in order to attack closures. Some use it as a negative example against particular closure proposal, some try to discourage Java language changes in general and some to promote other languages. When I read articles that start with "Generics are hard" and lead into "Generics are bad", I can't help thinking of the fox and the grapes. Yeah, they are hard. So is concurrency, NIO and many other things. So? That's why people create frameworks on top of Java.
Don't get me wrong - Java Generics have faults, and they are long known. Here's a hit-parade of my biggest complaints, but I will also mention some solutions I have used:
The way to work around it is by using type token or super-type token. As any workaround, it is limited, but it can solve part of the problem - Class#cast and Class#newInstance don't issue the annoying warnings.
2. Generic parameters not covariant
It is usually a good idea to use bound wildcards extensively.
3. No lower bounds support (except wildcards)
We can use static methods instead (ala extensions) with <T extends Super> rather than <S super Sub>
4. Verbosity, instead of more aggressive type inference
Not much to do, hm, learn to type faster? :-)
5. The angle brackets
Yeah, I hate them most when typing on blogger, luckily I am old enough to have been coding HTML in plain text editor a long time ago, so... back to GT and LT escapes.
BTW Java didn't die, it has simply grown beyond its hipness age. And I am glad that it spawned even better things, such as Scala. But there is a difference between "good" and "popular". Java is popular and not that bad, other languages may be better, but not as popular. Will Scala be willing to sacrifice some of its expressive power and shortcuts (gee, stuff like that reminds me why I don't code in Perl) to become simpler to learn/read and potentially more popular? Should it? (Ruby consciously didn't and ... didn't.) We shall see.
Thursday, January 10, 2008
"Machine capacities now give us room galore for making a mess of it. Opportunities unlimited for fouling things up! Developing the austere intellectual discipline of keeping things sufficiently simple is in this environment a formidable challenge, both technically and educationally."
Tuesday, January 1, 2008
"A bug in poker is a limited form of wild card."While looking for academic references for my properties project, I bumped into the expression problem - the write-up by Phil Wadler and follow-ups by Mads Torgersen and Matthias Zenger/Martin Odersky are really fun and educative readings.
This stuff caused me to re-read the the wildcards paper and I suddenly understood why I had this strange gut feeling about wildcard usage. Almost all learning material about Generics, including the wildcard paper itself, emphasizes the distinction between read and write methods - having a wildcard in a collection parameter prevents you from adding elements to the collection, but allows reading. This is true, but somewhat misleading. Actually, wildcard in the parameter allows us to call a method that returns the thing behind the wildcard and treat it as if the returned object is of the type of wildcard bound (or an Object, if the wildcard is unbound); the wildcard prevents us, however, from calling any method that takes "the thing behind the wildcard" as a parameter. Now obviously, to add something to a collection you need to call a method that takes that something as parameter, and it is indeed prevented, but other modifications are not disallowed, e.g. clear() .
The consequence of wildcard usage applies to any method, not just "write method", for example - containment test. So looking at Kevin's example, it now seems to me that doSomeReading method shouldn't have used a wildcard if it wished to perform a safe containment test - that's the catch (or should I say, hm, capture...)
Happy New Year!