On Blue-Collar Languages

I ran across this tech tip on using wildcards in Java generics. Pretty basic stuff, I thought. But I was amazed by the comments:

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.

Java generics? Not so simple. Check out this blog. Even a concurrency rocket scientist can be baffled by generics.

I am teaching a 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 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”.