


This article was extracted and adapted from the intro to a keynote I delivered in 2015 in Porto de Galinhas, Brighton, Austin, and Braga.

20 years ago there was a little explosion of programming languages. Computer hardware had advanced to the point where it was finally possible to write “serious” programs in what were called, at the time, “scripting languages”. Languages like TCL, Perl, Python, and, of course, Ruby.

These languages were different in that they had no compilation step before running. They were dynamically typed, and dynamic in other ways as well. They were higher-level than the general-purpose programming languages of the time. You didn’t have to manage memory in them. You didn’t have to keep track of loop indexes while iterating through lists or arrays.

As a programmer who came of age during this era, I was fascinated by these languages. I learned them, I tried to sneak them into my workplace, and I dreamed of a day when I might spend all day programming without once dereferencing a null pointer.

Now, in 2020, I live in a world of programming that has been permanently changed by the “scripting language” revolution. A huge percentage of software systems are written in high-level, dynamic languages. I haven’t been paid to work on C or C++ or Java code for many years. These traditional languages have been even been influenced by the scripting languages, adding features like foreach loops and lambdas.

Five years ago, I looked out on the programming language today, and saw a new explosion of variety. Many programmers were looking beyond Ruby or Python or Perl to languages that were either new or which hade received fresh interest and vitality. Languages such as Clojure, Erlang, Scala, Go, Elixir, Rust, Haskell, Elm, Idris, and even a newly-energized JavaScript.

Programming languages seldom die. But what I observed five years ago is even more true now: those who identify (or formerly identified) as Ruby programmers have begun to live in a post-Ruby world.

And this is exactly as it should be. When I met Ruby, it was in the company of a loose group of programmers who read The Pragmatic Programmer, and tried to follow its advice of learning a new programming language every year. They were people who believed that there was no such thing as an “Omega Language”; one language to rule them all. Just different tools, with different strengths and weaknesses.

Today we are in the midst of a cusp, or perhaps a few steps beyond it. We are at the beginning of the end of the “Ruby boom”. I already hear from companies looking for experienced Ruby devs to “maintain our legacy Ruby systems”.

“Legacy” is a word with a negative connotation in the programming lexicon. But legacies aren’t always bad. My first car was a Subaru Legacy wagon, and it’s the best car I’ve ever owned.

Seriously though, I think it’s worthwhile as we stand at this point, to reflect on what the legacy of Ruby and the Ruby community will be. What are the values that we will bring with us to new languages and new communities?

I have some thoughts on this, which I hope to expand on in future articles. They center around the values of informality, whimsy, and exuberance.

But if you’ve been part of this Ruby journey too, I’m curious to hear from you. What do you think of when you think of the Ruby legacy? What are the lessons that we have learned, and will teach others?

Published by Avdi Grimm


  1. 1) Rails, which made making web-apps SO much easier that I believe it played a significant role in the rise of the “everybody can code” movement, more and more people making web apps, and coding bootcamps.

    2) The Ruby community, which seems to have been leading the charge in software quality (at least outside of high risk fields like avionics and medical devices), soft skills, outreach to new developers, and treating other people fairly. Even better, since Ruby devs tend to be highly polyglot, they bring these attitudes into other communities.

  2. I think a lot of our friendliness to beginners and to socialising has been adopted outside Ruby itself. Not just in the language, but in conferences and meetups and so on. Ruby wasn’t the first to do these things, but it had a scale and centrality in the language (at least in the US) that was true of few other languages. But I think Ruby will be remembered for it.

    A lot of our embrace of metaprogramming has been central to Ruby, especially in the US, and is already starting to be adopted elsewhere. It’s hard to make a plausible Rails clone in any language without significant use of metaprogramming, and so there’s now a solid answer to the question, “why would I make my language/VM/environment more confusing by making it more complicated?” Outside of ‘scripting’ languages, there was a very real opposition to that.

    I think Ruby has been one more nail in the coffin of older forms of dynamism. I speak here of LISP macros (code that processes other parsed code at compile-slash-early-runtime to make new code) and code-generating code (like, literally writing out source files to disk.) Neither are fully dead. But the dominant narrative used to be that without those things, a lot of your expressiveness was severely limited. Ruby showed a different view with imperative/OO-style metaprogramming where language structures were modified at runtime rather than being FP-style generated by layered functions. And Ruby’s view of dynamism, which used to be a weird minority, has quietly become dominant (again, see metaprogramming and how it has become far more mainstream.) Macro-style dynamism got a killer app in Rails, but one that didn’t use macros or generate source files.

    Ruby’s legacy as a prototyping language is mixed — by serving that need very well we alienate a lot of folks who don’t primarily do prototyping ( But I think there will be a lot of later folks who see the value and follow in our footsteps. I very much agree with your “informality, whimsy and exuberance.” And perhaps I mean the same thing you do when I say, “dignity can be an obstacle, and trying to appear professional can be a complete roadblock.”

  3. Ruby isn’t the fashionable language it was a decade ago. And that’s a Very, Very Good Thing. The fashionistas have moved on; other languages, learned well, give the Rubyist more ways of looking at a problem even in Ruby; and there are still enough of us out there that hiring a good Ruby team, at least outside SE Asia, isn’t the crapshoot-in-the-desert it was in the early days.

    There are still enough good new things happening in Ruby, often under the influence of other languages/systems, to keep those of us who enjoy the language engaged and employed without (usually) feeling like we’re taking on the Sisyphean task of building modern tech around a 30-year-old production system written in COBOL or even ALGOL or PL/1, without tests or documentation. (Been there; done that; got the T-shirts; still occasionally wear them.)

    Ruby as a legacy language? Fine with me if management looks at it that way. Given resources, I can still hire and lead a team that will kick ass, take names, and have grins on their faces almost every (local) morning when they start work. After decades of building a career by guessing which then-bleeding-edge languages and tools are going to be economically viable 6-12 months down the line, I appreciate the change. I still learn a language or two every year (and I’ve been in the craft since 1979), but that no longer holds the fear for me that it did 30 years ago, when I was just becoming irrefutably aware of the fact that there will always be more unknown unknowns than known (anything). As Rumsfeld famously said, those are the interesting problems that tend to get people (or “merely” careers, in our case) killed.

    What lessons will we teach those who follow?

    Never stop standing up for beautiful (not fashionably complex) code.
    Knuth was right: “programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature [optimisation] is the root of all evil (or at least most of it) in programming”. Working code works, and that is not to be taken lightly.
    Rule 2 notwithstanding, if you don’t have solid test coverage (at least outside a very few tightly-regulated problem spaces), you don’t really know what you have, or what effect doing something to one part of it will have on some “obviously completely separate” part. Experience will trump expedience at least twelve times out of every ten.
    Iteration-friendly languages, like Ruby, lend themselves to agility. If “the customer never knows what he really wants until he sees it working” (highly reliably true), agile development, a cornerstone of Ruby commercial development, makes drastic changes far more feasible than languages whose cultures encourage Big Designs Up Front. You can use COBOL or FORTRAN for agile development; the typical dev who’s spent a lifetime in those languages, and the manager of that dev, is going to have to relearn a lot.
    As a community, we’re not afraid to change our minds based on experience. Metaprogramming (e.g., with DSLs) is a lot less prevalent in the Ruby code I see now compared to what I was reading a decade ago. Explicit code may be more tedious to write, but it is far easier to read, and you will read code far more often than you will (re)write it.

    Oh, and one more thing…

    If you’re not having fun, you’re (probably) not doing it right. Matz cites “developer happiness” as the foundational principle of Ruby and, to an absolutely astounding degree, he’s succeeded.

    I agree with you, Avdi, that there is not and can never be an “Omega Language”. For that reason, I profoundly but respectfully disagree with Noah Gibbs, above, when he talks about “one more nail in the coffin”. Languages never die; a good language, be it Ruby, Lisp, or RPG, will always have a certain problem space for which it is the most effective language. That problem space has historically often shrank as new, similar-but-different languages crowd onto the dance floor, but those who write off “old” languages as being “killed off” by new ones have never truly understood the power of the Force (the installed base). Java historically took a “McDonald’s strategy” in their advertising, citing “billions and billions of devices run Java”, to mix the slogans. I expect the market for Java maintenance devs to last for many decades to come, and for the (well-paid) Java devs in 2050 to be as hopeful and excited by the prospect of Java 60 as we now are by claims made for Ruby 3.

    Yes, this probably should have been my own blog post, but I’m just riffing off your idea. 😜

    • Oh, I don’t think LISP is dead. But I think the old-style forms of dynamism, like macros, are much less central even to LISP than they were. For an example, see a modern LISP like Clojure and compare it to how they used to do it in CommonLISP.

      I’m not suggesting at all that Ruby will kill LISP, but rather that other languages, LISP included, will tend more in the direction of a Ruby-flavoured approach to dynamism.

      Languages don’t (usually) die, but they change profoundly over their lifetimes. Neither C++ nor Perl5, for instance, are the languages they started out as. Ruby, certainly, has changed enormously over its existence.

      So I think we agree more than we disagree.

  4. Thought provoking article, thank you.


    Forgiveness, playfulness, but thoroughly tested


Leave a Reply
