This morning at Windy City Rails, Brian Shirai of Enova gave an excellent talk about Rubinius X, a language platform that extends the Ruby language. Rubinius X aims to, as Brian put it this January:
explore and address the many deficiencies in Ruby that continue to drive developers and businesses to other languages like Go, Clojure, and Node.js.
Sometimes at Meetups or in co-working spaces around Chicago, I’ll hear the word Rubinius tossed around as a newfangled thing—and because of that reputation, a thing that some developers haven’t prioritized learning and using. This evidences the fact that, to modernize a language, it’s not just the language itself that needs an upgrade: the developers who use the language also need resources to upgrade their understanding of the modernized language.
So what does Rubinius X offer us that we need to be excited about?
A lot of things! Here are just a few:
- Concurrency. Ruby famously (mostly) does not allow for concurrency. Only one thread can run at a time. No futures. No promises. Rubinius, by contrast, exploits the natural relationship between object-oriented language design and promise structure to make concurrency a possibility in Rubinius X.
- Optional labeling of argument types. this makes me so happy. Sometimes, labeling the types of things you want to pass into a method (say, as an integer, or as a message) makes the code clearer and easier to read by expressing behavior more plainly for other programmers. Ruby doesn’t do this in method calls, and Java requires it. So where’s the in between? It’s in Rubinius X. Label your arguments if you want. Don’t if you don’t.
- APIs that use keywords, rather than position-specific parsing instructions. Many of us have had to rule out an API for use in one of our applications because the data was dirty and inconsistent. Knowing that frustration, I breathe a sigh of relief to see that Rubinius X takes this into consideration.
And what’s it going to take to get developers to hop on board?
This one is simple: excellent documentation and code examples. Code examples, code examples, code examples. Preferably well-explained ones, but if that’s not the case, then at least something to play with. A few libraries for you to check out (note: some are Rubinius 2.0, not X):
- Obviously, the Rubinius repo
- Fancy, a language that runs on Rubinius
- GitLab, which shows off Rubinius 2’s functionality
So what’s next for Rubinius X? Well, according to Brian’s talk, more new functionalities and syntactic alternatives to Ruby. However, I must inject a word of caution. I felt that the talk this morning devolved into a bit of unwarranted Ruby-bashing which, despite not being too troubling in itself, evidenced some loss of sight of what makes Ruby so special in the first place.
So here’s where I contest you, Brian.
The Rubinius X website says:
Consistency is one of the most important characteristics of a system to aid understanding and the ability to evolve to meet changing demands.
This is true. This is absolutely solid. But I might suggest that we must define and measure “consistency” differently for Ruby than for other programming languages. Why? Because the objective of Ruby, as a language, when it came out in 1995, was to make a language that was “a joy to write.” I am going somewhere with this, so stick with me.
Why were other languages at that time not “a joy to write?” Well, they were designed to be easy for a compiler to read—not a human being. They spoke in a decidedly computerish language. Ruby, by contrast, meant to speak in a manner that much more closely resembled English—a human language. The language’s flexibility, its capacity for monkey patches and DSLs, even the dadgummed interpreter it runs on: all of those features support, in their design and in their implementation, the goal of creating a language that is consistent…with English.
Some of the examples that we saw this morning of Rubinius X’s functionalities move in a different direction: a direction that makes the language more consistent with itself, as a computer language, than consistent with English.
For example, Brian pointed out that we often write something like this:
puts "Hello World!"
“But,” he added, “everything in Ruby is an object, so why aren’t we doing this?” and offered the following syntax:
"Hello World!".puts()
It’s a valid observation, and the same could be said for lots of array methods and mathematical operations (this_array.[](0)
, anyone? 4.*(4)
, anyone?).
Why aren’t we doing this? Because it isn’t English. And Ruby is English, as much as possible. So, while the code might not be internally consistent, it’s externally consistent with our native, human language.
Put another way, the line "Hello World!".puts()
moves closer, from where we were in Ruby, to this:
System.out.println("Hello World");
That’s a line of code that many of you will recognize from another language, a popular and storied language…a language from which many people switch to Ruby.
So I humbly submit the following: while Rubinius aims to make Ruby internally consistent, there are already lots of languages that aim to do that. The point of Ruby, the spirit of the thing, is instead to be externally consistent—with the flawed, quirky, sometimes quixotic, inherently human English language that, despite its faults, we feel at home in and think in and dream in and use effortlessly. Ruby strives for that effortlessness. And to make it more internally consistent may, in fact, move the language away from the very foundations upon which it was built.
That is not to say anything against the admirable and exciting Rubinius X project: on the contrary, I can’t wait to explore the code further. That said, I would argue that Rubinius is more likely to capture popularity among Ruby developers when it sticks to the guiding principles that made Ruby popular in the first place.
Then again, if Brian is reading this and he’s in the serious business of fixing Ruby, I cannot waste this golden opportunity to indicate, for my personal gratification, what I would like fixed while the talented team at Rubinius is at it:
So here is my list of things for Ruby-Santa to stick under my tree:
- Sandboxing capabilities in Ruby: hoh-lee wow, does this need to be easier. Our options right now (besides $SAFE, which for a host of reasons is not secure) are jruby-sandbox for which, as the name suggests, we need to be using jruby, or _why’s no longer maintained freaky-freaky-sandbox, a sea-hardened, battle-scarred pirate of a code library with more than one C-related hack section in it. Like actual scars, these hacks limit the library’s flexibility. Make this easy, and the development community’s capacity to write dynamic, robust, secure apps for practicing, learning, and teaching code goes WAY up.
- Something better than strftime: so much of the Ruby language is so intuitive…and then there’s strftime. First of all, how do you even pronounce this? Sturf-time? Striff-time? Second of all, how is this not perplexing when you drop it into a code base?
- Consistency between hash and array methods. Hashes and arrays are essentially the same thing, mind you: one uses an integer to index a value, and the other one uses any object to index a value. That’s it. This viewpoint makes hashes much less terrifying and, in so doing, improves the developer’s flexibility. Problem being, everything about Ruby, down to the differing syntax of array and hash methods that do literally the exact same thing for their objects, respectively (
this_array << 5
looks nothing likethis_hash.merge!("integer" => 5))
, reinforces the idea that they’re fundamentally different (and also that hashes are weird, which is kind of racist against hashes. Object-ist?) If this were corrected, you will have parted the red seas of the hash construct for dozens of developers with distorted ideas about themselves and the world.
Nice post, thanks!
Just clarifying some JRuby points…
* The JVM itself also has excellent sandboxing (certainly more powerful than $SAFE), and that’s what several online code schools use to host running code on their servers. jruby_sandbox is also used, but that’s more about hiding or disabling Ruby features that require escalated privileges.
* JRuby has always had true, parallel threads, because the JVM has had parallel native threads for many years. I strongly recommend that anyone putting highly parallel code in production look at JRuby first.
* The JRuby team has experimented with optional static types, and in JRuby 9000 we’ll be exploring type inference and optimization in our new optimizing compiler.
I’m excited to see if the features promised in Rubinius X work well for users, so that we JRuby folks can (as we always have) work with the MRI core team to add them 🙂
Thank you for writing up your thoughts on brixen’s talk.