Thursday, December 06, 2007

RE: Groovy in Ruby: Implement Interface with a Map

Oops, he did it again! Having started off with the disclaimer that he is working with the Groovy community, Charles Nutter has a blog post that demonstrates how to do Groovy's coercion to a Map in JRuby.

Unfortunately, the irony in his post is that all he has done is demonstrate one of JRuby's shortcomings in terms of Java integration: it lacks built in coercion support. All of this is done whilst demonstrating only a small subset of what Groovy's as keyword is capable of.

The Ruby code demonstrated is as follows:
1. module InvokableHash
2. def as(java_ifc)
3. java_ifc.impl {|name, *args| self[name].call(*args)}
4. end
5. end
Which then can be used as a method like:
1. impl = {
2. :i => 10,
3. :hasNext => proc { impl[:i] > 0 },
4. :next => proc { impl[:i] -= 1 }
5. }
6. iter = impl.as java.util.Iterator
7. while (iter.hasNext)
8. puts iter.next
9. end
If you were to implement this in Groovy you could do:
1. Map.metaClass.as = { delegate.asType(it) }
However, in a further act of irony this code actually uses Groovy's built in coercion support and hence is in fact rather useless. All in one line of code!

What is even more amusing is his post conveniently skips over the fact that the as keyword is a general purpose coercion mechanism for all types of coercion operations, not just maps. For example this is also possible:

1. { println 'foo' } as Runnable
And it can be extended by implementing the asType method.

The most entertaining quote however is this one:

"Now if you ask the Groovy team, they'll make some claim like "it's all Java objects" or "Groovy integrates seamlessly with Java" but neither of those are entirely true."

Charles is trying hard to claim that JRuby's Java integration is no different to Groovy's. To those who want to try a little experiment have a go at this:

1) Write a plain JRuby/Groovy class
2) Write a Java class that creates a new instance of the JRuby/Groovy class and invokes a method on it
3) Set a break point on the Java class and step debug from the Java into the JRuby/Groovy class
4) Compile the sources and put them in a JAR
5) Put the JAR on the classpath of another app and write another Java class that references the JRuby/Groovy class

With Groovy and its joint compiler or IntelliJ IDEA's JetGroovy this is no problem, with JRuby you won't get passed step 2 without have to resort to introducing interfaces, creating dynamic proxies etc etc.

What the Groovy team says is this: Groovy has the same security model, the same debugger, the same profilers, the same object model, the same APIs, and close to the same syntax. For the Java developer its a no brainer.

8 comments:

Anonymous said...

I totally agree that this "Groovy is as foreign to Java as Ruby" stuff seems to be, plain and simply, FUD.

What bothers me the most is that all this JRuby work distracts from effort that could be better spent on Groovy.

I'm of the opinion that if you want Ruby that badly, just pick up your stuff and move to the Ruby camp. I'm not into language flame wars. Ruby sure seems like a good enough language.

But Groovy and Java are a far more intuitive and logical marriage. And I told Charles as much in his post. :) (Sorry Charles, couldn't help myself)

Anonymous said...

I like Charlie -- I happened to have had the honor of being on a panel with him -- but I've got to disagree with him about JRuby being a gift to Java developers. JRuby is a gift to Ruby developers, in the form of increased speed and the ability to leverage Java's ridiculously huge selection of open source libraries.

I don't see it as much of a distraction to Groovy, because it seems like the audience for JRuby is primarily Ruby-ists, and the audience for Groovy is primarily Java-ists. And I'm not sure trying to sell Groovy to Ruby-ists is going to fly: it's still too much Java for their tastes.

Anonymous said...

Why I think it's a distraction is because Sun has invested energy, time and money into JRuby on Java, rather than helping Groovy with its evolution. No doubt the Ruby-ists will point to that as a clear feather in their cap, but this shouldn't be a contest, with winners and losers. If it is, then in this instance, we're all losers.

I'd like to add that I'm not trying to insult Charles. He's clearly a really smart individual for being able to accomplish what he has. I just think his efforts and objectives would be better served in a pure Ruby environment. IMHO.

Charles Oliver Nutter said...

Ahh Graeme, I was expecting your reply. Whenever I so much as mention Groovy, you find it necessary to swoop in and defend the language like a mother bird. So a reply post was almost assured.

Since my point seems to have been entirely missed by several individuals, I'll spell it out here:

1. Groovy has excellent Java integration features, but it is not and never will be Java. There are many pieces of magic syntax, many non-Java constructs and concepts, and many, many new things that must be learned to use Groovy. It is assuredly a far more complicated language than Ruby, with much more complex interactions between features. Groovy is not Java. Don't sell it as being "just like Java" all the time, because it's a distraction, and understates the true value of Groovy.
2. Groovy's Java integration features can and will be implemented in other language implementations. In some cases, they won't be as clean or pretty as in Groovy, since Groovy's syntax frequently maps well to Java. In other cases, they may be better, having learned from Groovy's growing pains. But those features will most definitely be added.
3. There's no need to defend Groovy so vociferously anytime someone mentions it in a blog post. I didn't even think I was being negative...I was just reassuring Ruby users on JRuby that Groovy's Java integration features could be implemented on JRuby today or would be possible on JRuby tomorrow. The post wasn't about Groovy...it was about JRuby's amazing flexibility to adapt to new features without any modification to the language or runtime. Praising one language's beauty does not require other languages to defend themselves.

At the end of the day, however, I must admit I'm rather confused why you see fit to fight so hard for Groovy, even against posts that don't say a single negative thing about the language. Is there something wrong with Groovy I don't know about? Is there some insecurity about Groovy's future? It seems to me that many folks using Groovy today are very happy with the language. That's great...and certainly not surprising, since Groovy has gobs of great features. So why then the constant DEFCON 5, the constant Orange Alert for any mention of Groovy? Can't Groovy stand on its own merits without its users trumpeting their disapproval every time someone compares Groovy to another language?

Come on Graeme...Groovy's doing fine. Take the high road and let the language live its own life. It will be better for it.

Graeme Rocher said...

Charles, I must congratulate you, you're playing a very clever game of on the one side advertising how co-operative and welcome you are to work together and on the other side spreading FUD about Groovy with the aim of marketing JRuby.

In direct contradiction with point 3 of your comment I think it can only be due to your insecurities with JRuby's position as a far second place to Groovy in terms of Java developer adoption.

My problem with your post is that they are laced with snide remarks against the Groovy team and untruths about the Groovy language. I recommend if you don't want us to do our own marketing you take a different path to yours.

Anonymous said...

Charles, I really hate to wade into these language wars since I find them generally silly and pointless, but I have to say I agree with Graeme about a seeming hidden agenda of yours. I've picked up on this subtle theme when reading your posts over the last few months.

On the one hand you'll say something like "I'm hoping to start contributing some development time to the Groovy codebase, but for now I've mostly been monitoring their progress." as if to suggest you're big mates and really on board with the Groovy initiative, yet in your very next breath, virtually, you're making what I also consider to be 'snide' remarks about "the Groovy team", as if they're an opposing enemy force: "Now if you ask the Groovy team, they'll make some claim like "it's all Java objects" or "Groovy integrates seamlessly with Java" but neither of those are entirely true. Groovy does integrate extremely well with Java, but it's because of a number of features they've added over time to make it so...many of them not directly part of the Groovy language but features of their core libraries and portions of their runtime."

So much for "I didn't even think I was being negative..." or "even against posts that don't say a single negative thing about the language".

It's a bit of the old Trojan horse approach. Infiltrate, then attack from within. At least Graeme's standpoint is out there for all to see. He makes no bones about his opinion, whereas you seem to lace your sugar with poison, or your poison with sugar, I can't tell which. Why not just call a spade a spade, take up a position and argue its merits. Admit it, you have no real plans to further the Groovy cause, right? I know you're smart, cos I sure as heck couldn't do what you've done with JRuby, but I'd respect what you said far more if you respected the intelligence of the readers you're targeting. But that's just my $0.02.

Anonymous said...

Charles,


please dont pretend that you dont have a hidden agenda here. Even a blind person will see it when reading between your lines.

Anonymous said...

my schwartz is bigger than yours
*sigh*