Ruby in Ruby--Seriously

28 April 2008

All the attention that the various Ruby implementations are getting these days is a wonderful thing. Competition and lots of people trying out different ideas is a win for everyone. That said, there are still the silly human issues of ego and vested interest, always exacerbated by tossing some green into the mix.

I would definitely assert that JRuby is one of the more impressive stabs at a Ruby implementation. And we have, in large measure, to thank Charles for that. But, at the same time, Charles can write FUD like the best of them. I haven’t made it through the whole article yet (it does ramble on a bit), but I should point out a couple things.

Method dispatch is hard to get fast in Ruby, no matter what. Substitute a VM for an interpreter, C# for C for Java, whatever. And if you read carefully about what Charles is pinning his hopes on for the future of JRuby, it is precisely optimizations in the new JVM for better method dispatch. Rubinius will address these issues for sure. But instead of working on this with something like 143,866 lines of Java code, we have something like this: In the new C++ VM (which is not yet complete but substantially implemented), we have 12,619 lines of C++, and in our kernel directory, we have 23,882 lines of, what now, oh, right Ruby code. What you might miss when you think about the 143,866 lines of Java code is the several hundred thousand lines of C++ that make up the JVM. Hmm.

So, ultimately, Charles hopes to make JRuby fast using the same basic techniques that Rubinius does and will use. Except, it seems he’d rather use a 747 passenger jet to mow his lawn, rather than a comfy John Deere riding mower that your average small engine enthusiast can tinker with when something goes awry.

Seriously, the “Ruby in Ruby” meme must not die. It is an inspiration to a lot of folks and, most importantly, it has great promise. Press Charles on the issue and he will admit he’d rather have more of JRuby written in Ruby. I sense something of “bitter-gate” in Charles’ post. We don’t cling to Ruby because we can’t write C#, C, Java, etc. We don’t just like Ruby when it’s fun and fashionable and hyped. We are demonstrating that Ruby can be sanely implemented and push the state of the art for the language forward.

The C VM (named shotgun) was not our last word. Nor is the next generation C++ VM. They are both pragmatic steps toward a higher goal. And, let’s be very clear. We have not recently implemented a bunch of core methods in C. I’ve done two major pieces of rework recently that introduced a number of primitives (chunks of C code that access the VM directly). One was LookupTable, which was written in C because it is used heavily in the VM. However, it is exposed to Ruby code as well because, oh yes, we write a ton of stuff in Ruby, like stuff related to method and constant lookup. LookupTable acts a lot like a Hash, but separating it from Hash actually made Hash more clear and enabled writing even more of Hash in Ruby.

Another piece of work was optimizing some of String’s methods. You can see the performance enhancements in this ticket. I did introduce a couple new primitives in this rework, mostly to make a more sane set of composable primitives that were useful in many String methods. Primitives are a necessary fact of life in this composite implementation. Something has to bridge Ruby and C/C++. Also, by using a well-defined set of primitives, it makes it very easy to take our Ruby core libs and run them on something else. Ask Charles and he will tell you this. And if we write a little C/C++ to get the performance of a large number of Ruby methods up to par, that’s a huge win.

So again, the “Ruby in Ruby” meme is really important. Don’t let it die. And don’t let Charles tell you otherwise. While he can make snarky comments about our C/C++ VM, he should really look at his own kettle of 143,866 lines of Java code plus hundred thousands more lines of C++ JVM. The goal is a first-rate, powerful, extensible, approachable implementation of Ruby. Everyone in the Ruby ecosystem is contributing to that in various ways. Rubinius just seems to be putting the best pieces together, if I do say so myself.