Ruby's Roots and Matz's Leadership
/I recently had the excellent fortune to be invited to a gathering at CookPad in Bristol, where Matz, Koichi, Yusuke Endoh (a.k.a. Mame) and Aaron Patterson all gave great talks about Ruby.
I was especially interested in Matz’s first talk, which was about where he got inspiration for various Ruby features, and about how he leads the language - how and why new features are added to Ruby.
You can find plenty of online speculation about where Ruby is going and how it’s managed. And I feel awkward adding to that speculation — especially since I have great respect for Matz’s leadership. But it seems reasonable to relay his own words about how he chooses.
And I love hearing about how Ruby got where it is. Languages are neat.
You’ll notice that most of Ruby’s influences are old languages, often obscure ones. That’s partly because Ruby itself dates back to 1995. A lot of current languages didn’t exist to get these features from!
Ruby and Its Features
Much of what Matz had to say was about Ruby itself, and where particular features came from. This is a long list, so settle in :-)
The begin and end keywords, and Ruby’s idea of “comb indentation” - the overall flow of if/elsif/else/end - came from the Eiffel language. He mentions that begin/end versus curly-braces are about operator precedence, which I confess I’d never even considered.
On that note, why “elsif”? Because it was the shortest way to spell “else if” that was still pronounced the same way. “elseif” is longer, and “elif” wouldn’t be pronounced the same way.
“Then” is technically a Ruby keyword, but it’s optional, a sort of “soft” keyword as he called it. For instance, you can actually use “then” as a method name and it’s fine. You might be forgiven for asking, “wait, what does that do?” The effective answer is “nothing.”
Ruby’s loop structure, with continue, next, break and so on came from C and Perl. He liked Perl’s “next” because it’s shorter than the equivalent C structures.
Ruby’s mixins, mostly embodied by modules, came from Lisp’s Flavors.
“Unless” is from Perl. Early on, Ruby was meant as a Perl-style scripting language and many of its early features came from that fact. “Until” is the same. Also, when I talk about Perl here I mean Perl 5 and before, which are very different from Perl 6 - Ruby was very mature by the time Perl 6 happened.
He’s actually forgotten where he stole the for/in loop syntax from. Perhaps Python? It can’t be JavaScript, because Ruby’s use of for/in is older than JavaScript.
Ruby’s three-part true/false/nil with false and nil being the only two falsy values is taken from various Lisp dialects. For some of them there is a “false” constant as the only false value, and some use “t” and “nil” in a similar way. He didn’t say so, but I wonder if it might have had a bit of SQL influence. SQL booleans have a similar true/false/NULL thing going on.
Ruby’s and/or/not operations come straight from Perl, of course. Matz likes the way they feel descriptive and flow like English. As part of that, they’re often good for avoiding extra parentheses.
Matz feels that blocks are the greatest invention of Ruby (I agree.) He got the idea from a 1970s language called CLU from MIT, which called them “iterators” and only allowed them on certain loop constructs.
He took rescue/ensure/retry from Eiffel, but Eiffel didn’t otherwise have “normal” exception handling like similar languages. Ruby’s method of throwing an exception object isn’t like Eiffel, but is like several other older languages. He didn’t mention a single source for that, I don’t think.
He tried to introduce a different style of error handling where each call returns an error object along with its return value from a 1970s language called Icon from the University of Arizona. But after early trials of that method, he thought it would be too hard for beginners and generally too weird. It sounds a lot like what I see of GoLang error handling from his descriptions.
Return came from C. No surprise. Though of course, not multivalue return.
He got self and super from SmallTalk, though SmallTalk’s super is different - it’s the parent object, and you can call any parent method you like on it, not just the one that you just received.
He says he regrets alias and undef a little. He got them from Sather (1980s, UC Berkeley, a derivative language from Eiffel.) Sather had specific labelling for interface inheritance versus implementation inheritance. Ruby took alias and undef without keeping that distinction, and he feels like we often get those two confused. Also, alias and undef tend to be used to break Liskov Substitution, where a child-class instance can always be used as if it were a parent-class instance. As was also pointed out, both alias and undef can be done with method calls in Ruby, so it’s not clear you really need to use keywords for them. He says the keywords now mostly exist for historical reasons since you can define them as methods… but that he doesn’t necessarily think you should always use the methods (alias_method, undefine_method) over the keywords.
BEGIN and END are from Awk originally, though Perl folks know they exist there too. This was also from Ruby’s roots as a system administrator’s scripting language. Matz doesn’t recommend them any more, especially in non-script applications such as Ruby on Rails apps.
C folks already know that __FILE__ and __LINE__ are from the C preprocessor, a standard tool that’s part of the C language (but occasionally used separately from it.)
On Matz and Ruby Leadership
That was a fun trip down memory lane. Now I’ll talk about what Matz said about his own leadership of Ruby. Again, I’m trying to keep this to what Matz actually said rather than putting words in his mouth. But there may be misunderstandings or similar errors - and if so, they are my errors and I apologize.
Matz points out that Ruby uses the “Benevolent Dictator for Life” model, as Python did until recently. He can’t personally be an expert on everything so he asks other people for opinions. He points out that he has only ever written a single Rails application, for instance, and that was from a tutorial. But in the end, after asking various experts, it is his decision.
An audience member asked him: when you add new features, it necessarily adds entropy to the language (and Matz agreed.) Isn’t he afraid of doing too much of that? No, said Matz, because we’re not adding many different ways of doing the same thing, and that’s what he considers the problem with too many language features causing too much entropy. Otherwise (he implied) a complicated language isn’t a particularly bad thing.
He talked a bit about the new pipeline operator, which is a current controversy - a lot of people don’t like it, and Matz isn’t sure if he’ll keep it. He suggested that he might remove or rework it. He’s thinking about it. (Edit: it has since been removed.)
But he pointed out: he does need to be able to experiment, and putting a new feature into a prerelease Ruby to see how he likes it is a good way to do that. The difficulty is with features that make it into a release, because then people are using them.
The Foreseeable Future
Matz also talked about some specific things he does or doesn’t want to do with Ruby.
Matz doesn’t expect he’ll add any new fully-reserved words to the language, but is considering “it” as a sort of “soft”, or context-dependent keyword. In the case of “it” in particular, it would be a sort of self-type variable for blocks. So when he says “no new keywords,” it doesn’t seem to be an absolute.
He’s trying not to expand into emoji or Unicode characters, such as using the Unicode lambda (λ) to create lambdas - for now, they’re just too hard for a lot of users to type. So Aaron’s patch to turn the pipeline operator into a smiley emoji isn’t going in. Matz said he’d prefer the big heart anyway :-)
And in general, he tries hard to keep backward compatibility. Not everybody does - he cites Rails as an example of having lower emphasis on backward compatibility than the Ruby language. But as Matz has said in several talks, he’s really been trying not to break too much since the Ruby 1.8/1.9 split that was so hard for so many users.
What Does That Mean?
Other than a long list of features and where Matz got them, I think the thing to remember is: it’s up to Matz, and sometimes he’s not perfectly expert, and sometimes he’s experimenting or wrong… But he’d love to hear from you about it, and he’s always trying hard and looking around.
As the list above suggests, he’s open to a wide variety of influences if the results look good.