Skip to main content

On Blue-Collar Languages

Posted by cayhorstmann on May 4, 2008 at 9:16 PM PDT

I ran across href="http://blogs.sun.com/CoreJavaTechTips/entry/using_generics_with_wildcards_and">this
tech tip on using wildcards in Java generics. Pretty basic stuff, I
thought. But I was amazed by the comments:

style="float: right; margin-left: 2em;" />

  • Great post!! never knew about wildcards
  • I cant believe this. I cannot think how a wild card in generics fits
    into the java OOP theme. Upto now the rules were always simple
    and straight forward
    . In this case list object should have
    accepted all objects of sub classes by default. I feel generics in Java
    has made things complicated and confusing for the programmer.
  • If you find yourself writing way too many ? extends constructs and
    think you shouldn't need to, you probably should re-think whether you
    actually want an abstract class or whether an interface would do the job
    for you. [Huh?]

For the first time, I really understood what it means to be a blue-collar
language. In a blue-collar language, the rules are always simple and
straightforward. If something doesn't work, there is a clear error message,
either at compile-time or at run-time. Overall, Java did a great job with
that. Consider covariance of arrays.

Joe Bluecollar can convert a Employee[] array to an
Object[] array, and he never even worries whether that is safe.
If he then stores a Watermelon instance in the array, he gets an
ArrayStoreException. But that's not very common, and when it
does happen, Joe can see what the problem is.

style="float: right; margin-left: 2em;" />

Java generics? Not so simple. Check out href="http://gridgain.blogspot.com/2008/04/java-executor-service-rocket-scientists.html">this
blog. Even a concurrency rocket scientist can be baffled by generics.

  • Why in the world do I need to specify
    <? extends
        SomeInterface>
    for generics? What else am I going to do with an
    interface other than *extend* it. Well... I guess I can
    stare at it, but I don't think it counts.

I am teaching a href="http://www.sjsu.edu/faculty_and_staff/course_detail.jsp?id=3996">graduate
course in programming languages at San Jose State. One of the topics is
generics in Java and Scala. I thought my students would enjoy a topic of
current interest, but they are not happy. Variance and wildcards seem to
belong to that category of mind-benders that most people find impossibly
challenging, similar to the href="http://www.cs.nuim.ie/~jpower/Courses/parsing/node18.html">pumping
lemma or 2D array types in C.

(When teaching C, I used to patiently explain, with many examples, why the
type of an array declared as int a[3][4] is

int
(*)[4]
and not int**, but I was rarely successful. )

What is it about these topics that makes otherwise perfectly capable
programmers stop thinking and start guessing randomly? Maybe we all use
intuition more often, and formal reasoning less often, than we think? A
language that wants to capture the hearts and minds of the blue-collar
programmer needs to work very hard to have rules that are always simple and
straightforward. In Java, arrays are simple and straightforward. Wildcards
are not. I now appreciate how challenging it is to develop a blue-collar
language, and how much thought must have gone into the design of Java.

I don't mean to say that everything in the language has to be easy as
pie—we all know easy languages that lack power and expressiveness. But
the rocket science stuff ought not to be in everyone's face. In Java, the
rocket scientists can use annotations, reflection, and byte code engineering,
to deliver constructs that the blue-collar programmer finds intuitive to use.
The problem with Java generics is that they are too weak. For example, it is
not possible to implement a covariant array with an array store exception
(because of erasure). Instead, the wildcards leak out and give the
blue-collar programmer a headache.

What does that mean for closures? How leak-proof is the rocket science
stuff? With BGGA, for the most part, I think
it is pretty good, particularly when it comes to control invocations. Of
course, you'd never know from looking at all the blogs that show complex
syntax for writing closures. Well, using reflection, dynamic proxies, and
annotation processors is no picnic either. What counts is whether the
resulting artifacts are “always simple and straightforward”.

Related Topics >>

Comments

(not sure why it cut off my post...) ...the stated examples isn't even the worst of it. But it can move a lot of errors from runtime to compile time, and is therefore worth its weight in gold to learn. (WAY more important than complete unit test coverage, IMHO.) In any case, I think a lot of the confusion and discontent is mostly a syntax issue (along with extra support for runtime knowledge of generics). Thus I hope the closure folks learn a lesson and treat syntax as the first-class citizen it deserves to be. After all, syntax is your feature's user interface.

Personally I think generics are one of the best things Java has ever done. Anyone who's been waist-deep in C++ and tried to convert from a mytype to a mytype probably finds Java generic incredibly refreshing. And the fact that they're optional and can be mixed-and-matched with non-generics are also a nice bonus. Yes, the syntax gets a tiny bit hairy at times, and <? extends MyClass> isn't even the worst of it. That being said, use of generics can move a lot of bugs from runtime to compile time, and is therefore worth its weight in gold. It's just some of the syntax (and maybe some runtime knowledge) that needed a little cleaning up. I hope the closure folks learn a lesson and don't treat the syntax like an afterthought... it's the entire "user interface" to their feature and should be treated with the same usability concerns as any other HCI issue.

I do a lot of consulting in Java. Even in projects started new in 1.5 I've been seeing a lot of "@SuppressWarnings("unchecked");" scattered around like magic pixie dust to make problems go away. Most of this occurs in situations where a few wildcards would not only solve the problem far more cleanly, but would actually let the type checker do its job. It's ironic that so many people argue for Java over dynamically typed languages because of the type safety while ultimately treating Java as an awkward and verbose dynamically typed language. I don't have any magic answers. Types and typeful programming seem to get short shrift at the undergraduate level. That's perhaps not surprising given how much schools struggle just to convey the basics of recursion, algorithms, data structures, etc. They just run out of time before they can properly introduce types. And industry has historically been too stupid to know that it would be far better off with a bit of internal training. Finally, as to your point about keeping the rocket science stuff out of people's faces - I think that Java platform has a good story to tell here. There are languages like Scala and Clojure which all about very rocket sciencey stuff (Scala in its type and module system, Clojure in its macro and concurrency system). Perhaps its time for the Java designers to recognize that the Java language doesn't need to be, and indeed can't be, one size fits all.