Nannies for Blimps!
In the old days, the compiler was your nanny, because computer resources were expensive and delicate and huge, like a giant hydrogen blimp. You want to fly the blimp, baby, you better be really good at flight plans.
So static-typing was one of several ways to prevent us from blowing up the blimp at runtime. (This metaphor may not work for too many more paragraphs, but I am flying with it for now anyway.) Static-typing is really a sort of BDUF (Big Design Up Front) enforced at the language level. It imposes design straitjackets that only become plain once a dynamic language has removed them from you. (Wow! You can do THAT in this language? Really? Look at how much less code that is.)
The Nanny is Not Groovy, Man
Extending designs in Java is genuinely hindered by static typing. It’s no longer a political issue, it’s just plain fact. And I don’t just mean because it takes 400 characters to print “Hello World.” No, I mean the kinds of shenanigans imposed on every type you inherit or use or create. Think: generics, and how long it took for Java to get them, and what a pain in the arse they are. The Nanny really is everywhere in Java, to my mind.
Bruce Tate, Stuart Halloway, Justin Gehtland, and others have made passionate, convincing argument that (for example) convention-based Rails programming as a means of getting an enterprise web app “off the ground” (so to speak) may be faster than the lightest-weight J2EE frameworks by a factor of 10. Maybe more than one factor of 10. Sheesh, that Nanny is EXPENSIVE! How would your stakeholders like it if you could produce 10 times as many web applications to solve enterprise problems than your teams can today?
The catch, of course, is Ruby and its still relative dirth of supporting libraries, frameworks, and similar open-source support. And Ruby syntax looks wonky to us old Algol-based fuddy-duddies. This is why I am personally so attracted to Groovy and Grails. (Introduced to me by Andrew Glover of Stelligent and Chris Judd at CodeMash in Ohio last month.) All the convention-based goodness, plus leverage of my Spring and Hibernate experience, and I can still use the Java stuff that the mean Nanny pounded into my head over the years. (Just the good stuff. She’s not a completely mean, insane, dictator nanny, I can now see in retrospect.)
Look Nanny, No Unit Tests! (Uh Oh.)
So off we go to a dynamic language, full of our static-typing outrage. The catch, of course, is this: because you can send a “divideYourselfByZero” message or any odd message you like to the integer 42 in languages like Smalltalk, you can get runtime errors of the sort that would curl a Java programmer’s hair.
Does it suddenly make a bit of sense why the first member of the xUnit family was, in fact sUnit? My question for the Smalltalk crew is this: before you had sUnit, how the heck did any of you keep your jobs? The production deployment problems must have been Hindenburg-spectacular. (I’m partly kidding. Actually, it turns out, the really good Smalltalkers had other tricks up their sleeves to avoid runtime disaster.)
So the bottom line is this: with dynamic languages, You Have No Choice but to develop exhaustive, requisite suites of true unit-level isolation tests. Oh, plus end-to-end tests, and several other automated test varieties. This is the equivalent of venting out all the Hydrogen and replacing it with … Helium! Yay! Doesn’t explode, a bit more expensive, for sure, and not quite as “lifty,” but way safer, and you can still fly.
With dynamic languages, you have the authority and responsibility to be an adult, not a child. No more Nanny, so no more stepping out into the street before you look both ways.
Note to Recruiters: Hire the Guys Who Know Dynamic Languages, No Matter What They Charge
Power Programmers, Alpha Geeks, the ones who some now claim in public (reasonably, I believe) can outproduce “vocational programmers” by a factor of 10 or more (there is that same math, hmm)? It turns out that one of the primary indicators of one of those guys or gals is that they just cannot keep their hands off of lots of different languages, and operating systems, and computers, and you name it. Some of them actually play banjo! They are really good at comparing entire language systems and development systems to one another. They really like dynamic languages, because they are so much faster and cleaner and better. And they really, really like unit tests, because suites of them save their behinds so frequently.
Oh, BTW, you know what true alpha geeks are all on about these days? A good old idea come full circle: functional programming. Oh, and also, BDD. Whee, here we go!
Alpha Geek example: my alpha geek pal Dimitri says “dynamic languages are so much more expressive it’s not even funny.” He says that when he noticed that Ruby does not require generics, “I almost started crying.” He says “I think the whole thing can be summarized as: static typing breeds incidental complexity”. Great quote. And he correctly points out that in the emerging world of Domain-Specific Languages (DSLs), dynamic languages are absolutely vital.
So save the really big programmer salaries for the ones who (A) know unit testing backward and forward, including TDD, (B) know multiple languages, and program avocationally and recreationally, and (C) can spout endlessly about the benefits of once-seeming exotica like dynamic languages and functional programming. That, at least, would be my agile alpha geek definition. There are other kinds of alpha geeks, certainly. In my big enterprise app world, I need the agile ones.
Hire guys like Dimitri. Make sure your team has a ratio of at least 1 alpha geek to every 3 or 4 non alpha geeks. And be the kind of boss and organization that alpha geeks love to work for and with (yet another blog topic, for another time).
And be the kind of boss who enables non-alpha geeks to find their way to alpha, if they want it. Again, another blog for another time.
I couldn’t agree with you more Patrick. I’ve been doing a lot of reading and listening to people talking about Groovy and Grails, especially with the 2G conference coming up soon. I don’t know if I’ve quite reached Alpha Geek status yet, but frankly I get kind of excited. This year’s resolution for me is to learn more Groovy, and incorporate it into my everyday work, because after all it is Java 2.0 and I don’t have to quit doing Java just to do Groovy…
Dude. You are hopelessly alpha. I’ve paired with you, and I’ve seen your bookshelf. You are writing a book, for crying out loud. You are a special category of “indigo child alpha geek:” not only can you not keep yourself from learning new geeky stuff, you can’t stop talking about it.
Hey Patrick!
I actually have some pretty serious experience with the internals of groovy and grails, and don’t have very positive words for it. I’m a huge dynamic languages guy (with some knowledge of the very real trade offs), but I must say my experience with both groovy and grails was exceedingly disappointing.
It’s a complex story, but the gist is:
– Groovy is a great language with a pretty poor implementation. Looking at the decompiled bytecode, it seems to have a ratio of something like 8 to 1 reflection to actual business logic. The performance suffers as you would expect – it’s a few thousand times slower than equivalent Java code. This is normally not a big deal (both Ruby and Python are a whole lot slower than both Java and C++), but it’s significant enough in this case that even simple unit tests can take multiple seconds. SECONDS! Throw together a few hundred unit tests, and you have a significant slowdown of developer productivity just from the language implementation alone. Throw in some issues like API breakage on perfectly valid Java API’s (jmock doesn’t work with Groovy 1.5, jbpm exposes package names that break Groovy’s interpreter) – and you have a serious pain in the butt.
Worst of all – the tool support is horrendous. Working with Groovy in Eclipse or IntelliJ is a major course in frustration. The two way Java-Groovy support is flaky at best, and each plugin for each IDE currently has a set of bugs that make them virtually unusable for big jobs.
Refactoring support is really non-existent. Beyond simple tasks like method rename, it’s really a no-go. Say what you will about a nice agile language, I LOVE my refactoring. Smalltalk invented it, so there must be a way to provide this ability to true dynamic languages.
– Grails – now my experience with grails is less than Groovy, but it seems to inherit and add to many of the issues with Groovy. If you’re working within their world view – you’re ok. If you want to do things like have a multi-project system with instant IDE updating (no jar rebuild to test), you’re essentially hosed. Maven2 support is nothing but a false promise with the existing plugin (you don’t get to depend on any maven dependencies or sister projects). This is a really critical feature on big projects – and I’m surprised and disappointed that they don’t support it. Finally the GWT support was very half-baked.
So – all in all, my experience with Grails/Groovy was far less enjoyable than the experiences I’ve had with other dynamic languages. I’d recommend to all interested to give it a couple years and see if these problems still persist.
I hope life is going good for you Patrick. Talk to you soon!
– Dave…
Dave:
I know you well and I trust your verdict on this; I don’t have the experience with either of these projects that you do. And thank you for the deep exploration! Sad news, though. I was hoping these projects were further along in terms of being truly robust.
You may want to contact Andy Glover and Chris Judd to get their feedback on how Groovy and Grails are expected to evolve. If your experiences are typical, and if these projects can’t keep up with the demands of industrial-strength projects and their developers, then no amount of buzz will save them.
What would it take to improve the Groovy language implementation to rely substantially less on reflection?
Cheers, dude,
–Patrick
Dude! I’ve been waiting for your next post. What’s up your sleeve?
Charlie