It is with some dismay I’ve been reading the latest Groovy discussions on JavaLobby. I’ve spent quite some time learning Scala, so it bothered me a bit that I minded another competing language a spot in the limelight. Why would I care? To me as a consultant, language fragmentation is great. Today only a few languages are in widespread use, and there is no problem finding a skilled consultant at a reasonable price. But if Java and C# fragments into JRuby, Groovy, Scala, Jython, F#, IronPython, etc, then I’m better off since I will probably be able to charge more per hour in such a fragmented market.
As an anlogy, what if we all were driving either Fords or Mazdas – competition in the car mechanics market would be fierce since there would be so many that could fix our cars. Today we have dozens of car makers, and I can’t drive my Toyota to a Volvo mechanic and expect him to be able to fix it. Instead I have to drive to one of the few specialized Toyota mechanics that charge so much my nose starts bleeding when I open my wallet to pay.
What we all want is a more productive language, but we don’t want to throw away all our old frameworks and libraries. Which is where JRuby, Groovy and Scala comes in. Some people believe Groovy is the winner, because its syntax is so close to Java. But I think the only major difference, really, is where you declare the type:
// Java and Groovy
String a = "Xyz";
// Scala, knows it's a String by type inference
val b = "Xyz"
// Scala, if you wish to be explicit about the type
val c: String = "Xyz"
And, seriously, how hard can it be to learn the difference?
All these new languages have amazing features that Java doesn’t have, but dynamic typing isn’t one of them. Sorry, nobody can convince me that throwing away static typing is a good thing. Some argue that dynamic typing is preferrable during prototyping, when the code base is in big flux. At a later time, when the design has stabilized a bit, people claim you can re-implement it in a language with static typing. Sorry, that just don’t make any sense to me. During prototyping, when you’re fumbling around in the code to see where the abstractions are, is when I need static typing the most. Otherwise Liskov’s Substitution Principle will be the axe that chops off my fingers in the early morning when bright light shines on my nightly prototyping. (Sorry, I got a bit carried away there). Being sloppy about types is not an option.
Regardless, these new language features are way cool, and will hopefully be able to bring programming productivity up quite a bit. But don’t fool yourself – this productivity isn’t all that important, at least not for big projects. At Microsoft they write 1500 lines of code per year. Do you really think it matters much if it is in VB or F#? What really matters is readability. The reason they only write 1.5 KLOCs a year is most likely that their existing code is in such a mess that you need to be superhuman to understand it (and have 3 testers ready behind you at every moment).
And Java is pretty readable, IMHO. It is a rather simple language with few hidden surprises. At the moment my Scala reading skills is perhaps 10% of me reading Java. I hope to bring that up quite a bit, because Scala code isn’t 10 times more compact than Java.
The other half of the problem, if language features and compact readable code is the first half, is multi-core processors.
Most of us aren’t smart enough to manually split our applications into more than a few parallelly executing threads. We’re certainly not smart enough to spawn threads to keep 16 cores churning. In face of this problem, are we going to pick a new language with a rather immature VM (Ruby) or a language with a really complicated virtual dispatch scheme that complicates attempts of the VM to split jobs to several cores (Groovy)? It just doesn’t make sense to me!
Why not pick a language with immutable data structures and a really elegant actors library that gives us message passing concurrency? Why pick a language that makes it hard for the VM to parallellize, when we can pick a language where parallellization is a built-in feature from the start?
I think the choice is simple. Only one language solves the whole problem: Scala.