Ruby in Ruby--Seriously

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.

10 Responses to “Ruby in Ruby--Seriously”

  1. Finanzamt Says:

    Do you think that JRuby has bright future? Do you expect that large company will be using it or it will be only startup feature like rails now?

  2. Brian Says:

    Finanzamt,

    I’m sure JRuby has a bright future. The folks I know who are working on it are bright and enthusiastic. The integration with Java is a point of great value to the folks who I know that are using it. And the JVM developers are certainly not resting on their laurels.

  3. Charles Oliver Nutter Says:

    A few corrections:

    • JRuby isn’t going to be fast…it is fast already, if fast is comparing to Ruby 1.8. And the techniques put in place in Rubinus largely followed the same techniques in JRuby: call site optimizations, for example, which Evan and I discussed at length before he implemented them. Of course we can never be fast enough, and we’ll continue improving things in future releases. Some of those releases may support “even better” dynamic dispatch in JDK7, but we’re definitely not counting on it. JRuby is fast, today, on current JVMs.
    • I agree that the ideal of “Ruby in Ruby” needs to live. It’s valuable to have an implementation in Ruby, and some day it might be practical to run real apps on Rubinius’s kernel, whether on the current VM or on a future one. I’m sure it will happen, maybe even soon. But the meme I refer to is that Rubinius is somehow automatically better than all other implementations simply because it’s written in a higher percentage of Ruby. Maybe that will be the case someday, but it hasn’t been proven yet. There are lots of folks working on it, and I want to help as well. But it’s going to take time. Ruby in Ruby is a great ideal, but it’s entirely unknown whether it’s the best path to follow yet.
    • Finally, the only reason the “Ruby in Ruby” meme bothers me so much is that after Evan’s RubyConf 2007 presentation it’s been used as a club to claim non-Rubinius implementations are inferior. Some of that is opinion that can’t be helped, but a lot of it is driven by Evan’s stupid, stupid slide about relative lines of code, which was inaccurate and a gross misrepresentation of affairs. His claim that JRuby is somehow not for Ruby programmers was a public insult that’s never really been retracted. So maybe I harbored some ill will. But it wasn’t very nice. We want to be nice, don’t we?
  4. Brian Says:

    Charles,

    I still think it’s a fair point of comparison. Rubinius does have a lot of Ruby code. And the goal is Ruby in Ruby (or RiR). Whether we approach that asymptotically or as a monotone function or as a fractal function could be debated. It is also great if this goal attracts people to working on any Ruby implementation, since the number of folks actively doing so used to number in the low tens (a WIG if ever there were one). Knowledge of Ruby internals is a skill that translates.

  5. Wilson Bilkovich Says:

    Rubinius IS automatically better than other implementations because it is written in a higher percentage of Ruby.

  6. Rob Whelan Says:

    @Wilson Bilkovitch: You’d have to follow that up with a “because”... it seems pretty obvious that the first practical measure of a Ruby interpreter is how effectively it executes Ruby scripts. That’s its purpose, its reason for existing.

    How that implementation is created, who works on it, what languages and technologies it includes, how large it is, or any of these other things are secondary goals (not meaningless, but… secondary). They are all there to support the primary goal, which is solid execution.

    If including more Ruby code in the interpreter implementation encourages more participation, and enables shared improvements across different interpreter implementations, that’s wonderful, but only because it helps the primary goal. It’s not a goal in itself.

    How could it be? Imagine a Ruby interpreter that was far more RiR than Rubinius—but which was highly unstable and buggy, with terrible performance and an enormous memory footprint. Apparently, some folks would say “it’s automatically better than Rubinius”... what nonsense.

  7. Brian Says:

    Rob,

    I’d offer that it makes as much sense to reverse your two goals. In other words, if the primary goal is writing the best code, it will be simple, well-designed, efficient, extensible, powerful, maintainable, and have execution characteristics that achieve the secondary goal: performance and stability in the execution of Ruby code. Of course, those attributes listed are like a constraint problem. You can’t have the “maintainability” component overriding the “efficiency” component, for example.

    For too long, the goal of super-fast whatever has produced horribly complex systems that basically grind to a halt because they are far on one end of the maintainability spectrum. I think the folks at VPRI are really on the right path in terms of better ways to write programs.

    Also, please be kind to the other people who express opinions here.

  8. Rob Whelan Says:

    Hi, Brian, I’d say “long-term” is a good addition to “stability and performance”, but that doesn’t mean you can reverse the goals.

    Try the test of imagining you’ve met one goal but not the other. If your code is a thing of beauty but for whatever reason (e,g., flaws in dependencies, or missing pieces) your product is unstable, incomplete, or very poorly performing, you’ve got a ways to go before you have a useful interpreter.

    If your code is horrible and unmaintainable but your interpreter is solid as a rock & flies like an arrow, well, you have a successful interpreter that will probably see a lot of use (though here’s where adding “long-term” to the primary goal is probably a good idea, because the chances of that would be slim!).

    I absolutely agree that unmaintainable spaghetti code, overly complex & inflexible design, etc.. all of these things are important, and can ruin your shot at creating a successful interpreter. You might also hamstring an interpreter long-term with decisions you make in the short-term, and this is all worthy of discussion—because it impacts the primary goal.

    Apologies for the unneeded snark….

  9. Chloe Baby Says:

    I think big time commercial companies developing sites and applications on ruby is just not realistic. The support just isn’t there compared to say, php, asp or java.

  10. Adult Ühler Says:

    So FUD has infected Ruby too :(

Sorry, comments are closed for this article.