Saturday, July 07, 2007

Travel Broadens You

Not too long ago, I was in India to speak at JAX India. The conference was held at a science center in downtown Bangalore, and the speakers were staying in a hotel several miles away. One of the interesting things about India is that you can hire car services for cheap, so the conference organizers had a platoon of cars at our disposal, for trips to and from the conference center, which took about 20 minutes (it would be about 5 minutes if there was no traffic, but apparently that state never exists in Bangalore).

While driving to the conference center a couple of times, we passed a part of town where there were several cows lounging in the road, in amongst the traffic. No one even noticed: the traffic flowed right around them as if they were any old standard barrier in the road. Of course, it struck me as very odd, because I almost never see cows on the main roads of Atlanta.

It made me realize that people can get used to and habituate anything. During the conference, I talked to Java developers about some of the odd things in Java. Java has its share of strange behaviors (generics, anonymous inner class syntax, the recursive Enum definition) that look to strangers as odd as a cow standing in the road. Because Java developers are accustomed to seeing these cows all the time, they don't even notice anymore. But it strikes tourists as very odd and surprising.

Here is a concrete example. Groovy makes it really easy to interact with Java objects, including those that follow the standard JavaBean specification for get and set methods to form properties. In Groovy, when you create a new class, you can create your properties using the get and set style of coding, yet when you call the property, you can leave the get and set off.

class Foo {
def name

def getName() {
return name.toUpperCase()

def setName(value) {
name = value

foo = new Foo() = "Homer"

Now, when I refer to what looks like a regular public field (to a tourist), I get the uppercase version because of the automatic mapping to a getter. To a Java developer, this auto-magic mapping from the property methods to actual properties seems as normal as can be. However, to a Java tourist, it looks as strange as a cow in the road.

This suggests 2 things to me. While every language has its own bizarre quirks, it is the seemingly irrational stuff that turns off tourists to the language. Do you really want to go into a history of the JavaBean specification to the poor Python programmer who's vacationing in JavaLand so that they can understand this weird but expected behavior? And will they possibly stay awake for it? Probably not, so they'll just say something like "Wow, Java's broken" and move on. I think this hampers attempts to expand Groovy's meme outside the Java world. I know there are efforts to port Groovy to the .NET platform, but will it possibly attract any .NET developers because of its unabashed Java-ness?

The other thing this suggests to me is the advice in The Pragmatic Programmer to learn a new language every year. Just as physical travel broadens you, traveling to a strange language broadens you too, so that when you see cows in the road back home, you understand that it's not normal for everyone. Stranger in a strange language, anyone?


Unknown said...

Neal- it's not clear from your example what you are trying to convey-- in Groovy, you don't actually need to create a setter and getter method (as they are generated for you when you create a class member) but beyond that-- just like in Python, everything you define in a class in Groovy (like methods and properties) are implicitly public. I don't see why that's strange-- it is the behavior defined by Groovy, which is obviously different than Java. No doubt, traveling into other languages certainly does broaden one's horizons...

Neal Ford said...

Fair enough, but what I was trying to convey is this: even if you know that creating a field automatically creates public access to it, you still would be puzzled that, when you actually set a value for the field, it goes though the setter. So, if you were doing something odd like adding a call to toUppperCase() on the return from the setter, it would invisibly call the get method from what looks like public field access. The point is that you have to understand a bunch of relatively arcane information about property dispatch to understand why it does some things and not others.

Neal Ford said...

In fact, I modified the example to illustrate this -- thanks for the comment that encouraged me to make it clearer!

Shane said...

Hi, if I understand you correctly, this example should come as natural for a .NET developer or a Ruby developer, right? So maybe if you do travel long enough, the lack of such will surprise you? :)

Neal Ford said...

I think this example would surprise any non-Java developer; too much magic convention-based indirection going on.