Here we are, in the waning months of 2011. Ruby and its ecosystem are a bit of an incumbent these days. It’s a really great language for a few domains. It’s got the legs to become a useful language for a couple of other domains. There are a few domains where I wouldn’t recommend using it at all.
Ruby’s strong suit
Ruby started off as a strong scripting language. The first thing that attracted non-tinkerers was a language with the ease-of-hacking found in Perl with the nice object-oriented features found in Java or Python. If you see code that uses special globals like $!
and $:
or weird constants like ARGF
and __DATA__
and it mostly lacks classes and methods, you’re looking at old-fashioned scripting code.
As Ruby grew, it got a niftier way of doing object-oriented programming. Developers started to appreciate it in the same places they might use Java or Smalltalk. A few of the bravest started building production systems using a nice object-oriented language without the drawbacks of a high-maintenance type system (Java) or the isolation of an image (Smalltalk). This code ends up looking a little like someone poking Ruby with their Java brain; they’re not using the language to its fullest, but they’re not abusing it either.
Out of the OO crowd exploded the ecosystem of web frameworks. There were a few contenders for a while, but then Rails came and sucked the air out of the competitive fire. For better or worse, nearly everyone doing web stuff with Ruby was doing Rails for a few years. This yielded buzz, lots of hype, some fallings out, some useful forward progress in the idioms of software development, and a handful of really great businesses. At this point in Ruby’s life, its interesting properties (metaprogramming, blocks, open classes) were stretched, broken, and put back together with a note pointing out that some ideas are too clever for practical use.
As Ruby took off and more developers started using it, there was a need for integration with other systems. Thus, lots of effort was put into projects to make Ruby a part of the JVM, CLR, and Cocoa ecosystems. Largely, they delivered. At the end of 2011, you can use Ruby to integrate with and distribute apps for the JVM and OS X, and maybe even Windows. This gave Ruby credibility in large “enterprisey” shops and somewhat freed Ruby from depending on a single implementation. The work to make this happen is non-trivial and thankless but hugely important even if you never touch it; when you see one of these implementers, thank, hug, and/or bribe them.
Ruby could go to there
WARNING Prognostication follows WARNING, your crystal ball is possibly different than mine
Scala, a hybrid functional/object-oriented language for the JVM, is a hot thing these days. A lot of people like that it combines the JVM, the best ideas of object-oriented programming, and then swizzles in some accessible and useful ideas from the relatively untapped lore of functional programming (FP). So it goes, Ruby already does one or two of these things, depending on how you count. The OO part is in the bag. Enumerable
exposes a lot of the same abstractions that lie at the foundation of FP. If you’re using JRuby, you’re getting many of the benefits of the JVM, though Scala does one better in this regard right now. Someone could come along and implement immutable, lazy data structures and maybe a few combinators and give Ruby a really good FP story.
Systems programming is traditionally the domain of C and C++ developers, with Java and Go starting to pick up some mindshare. Think infrastructure services like web servers, caches, databases, message brokers, and other daemon-y things. When you’re hacking at this level, control over memory and execution is king. Access to good concurrency and network primitives is also important. Ruby doesn’t do a great job of providing all of these right now, and Matz’s implementation might never rank highly here. However, one of the promising aspects of Rubinius is that they’re trying very hard to do well in terms of performance, concurrency, and memory management. If Rubinius can deliver on those efforts, offer easily hacked trapdoors to lower level bits, and encourage the development of libraries for network and concurrent programming, Ruby could easily turn into a good solution for small-to-medium sized infrastructure projects.
Distributed systems are sort of already in Ruby’s wheel house and sort of a stretch for Ruby. On the one hand, most Ruby systems already run over a combination of app servers and queue workers, storing data in a hodgepodge of browser caches, in-heap caches, and databases. That’s a distributed application, and it’s handy to frame one’s thinking about building an application in terms of the challenges of a distributed system: shared state is hard to manage, failure cases are weird and gnarly, bottlenecks and points of failure are all over the place. What you don’t see Ruby used for is implementing the infrastructure underneath distributed applications. Hadoop, Zookeeper, Cassandra, Riak, and doozerd all rely on both the excellent concurrency and network primitives of their respective platforms and on the reliability and performance those platforms provide. Again, given some more progress on Ruby implementations and good implementations of abstractions for doing distributed messaging, state management, and process supervision, Ruby could be an excellent language to get distributed infrastructure projects off the ground.
Unlikely advances for Ruby
Embedded systems, those that power your video game consoles, TVs, cars, and steroes, rely on promises that Ruby has trouble keeping. C is king here. It provides the control, memory footprint, and predictability that embedded applications crave. Rite is an attempt to tackle this domain. The notion of a small, fast subset of Ruby has its appeal. However, developers of embedded systems typically hang out on the back of the adoption curve and are pretty particular about how they build systems. Ruby might make in-roads here, but it needs a killer app to acheive the success it currently enjoys in application development.
Mobile apps are an explosive market these days. Explosive markets go really well with Ruby (c.f. “web 2.0”, “AJAX”, “the social web”), but mobile is different. It’s dominated by vendor ecosystems. Largely, you’ve got iOS with Objective-C and Cocoa, and Android with Java and, err, Android. Smart developers don’t tack too far from what is recommended and blessed by the platform vendor. There are efforts to make Ruby play well here, but without vendor blessing, they aren’t likely to get a lot of traction.
Place your bets, gentlemen
Tackling the middle tier (object/functional, distributed/concurrent, and systems programming) is where I think a lot of the really promising work is happening. Ruby 1.9 is good enough for many kinds of systems programming and has a few syntactic sugars that make FP a little less weird. JRuby offers integration into some very good libraries for doing distributed and concurrent stuff. Rubinius has the promise to make those same libraries possible on Ruby.
Really sharpening the first tier (thinking about how to script better, getting back to OO principles, fine tuning the web development experience, improving JRuby’s integration story) is where Ruby is going to grow in the short term. The ongoing renaissance, within the Ruby community, of Unix idioms and OO design is moving the ball forward; it feels like we’re building on better principles than we were just two years ago. The people who write Ruby will likely continue to assimilate old ideas, try disasterous new ones, and trend towards adopting better ways of building increasingly large applications.
When it comes to Ruby, go long on server-based applications, hedge your bets on systems infrastructure, and short anything that involves platforms with restricted resources or vendor control.
No matter how distasteful we find it, we must face the grim conclusion that the future belongs to JavaScript … or one of its sinister offspring.
JSR-292!
JavaScript is a pretty good vector to sneak ideas into the mainstream these days. Even without movement on the core language, JavaScript has the rudiments of a mostly tolerable language. The interesting question is whether it can pick up a good parallel implementation.
Hi Adam!
Very enjoyable read and I find myself in full agreement on all major points. I just have a few minor quibbles.
1. Ruby has immutable lazy lists in the form of generators.
2. Ruby has a number of solid distributed systems implementations, the most mature of which is probably Cloud Foundry. Derek and his team have built an amazing distributed system in pure Ruby that includes a message bus, a presence/heartbeat manager, a routing layer, and so on; and which solves a non-trivial real world problem in a very elegant and instructional way.
The second sounds interesting, is there someplace I can read a coherent (non-marketing/enterprisey) breakdown of said system?
Adam, the best place to read the non-marketing breakdown is on github (aka, the source code). Having said that, for a very brief crash course, you can take a look at my post dating back to the original release.
I do think you may be underestimating Ruby on the infrastructure side – there are many companies out there which rely on Ruby as the core of their service. The thing is, the most successful ones don’t tend to share too much about it either (wish that was not the case).
I’d love to hear from those doing infrastructure in Ruby. Daemons and databases are way more interesting to me, at this point, than web frameworks. :)
“There were a few contenders for a while, but then Rails came and sucked the air out of the competitive fire. ”
No it didn’t. Lot’s of good and vibrant stuff still going on. In fact, long-term, the better-planned, lighter, leaner Web tools such as Ramaze and Sinatra will have a more interesting future.
Also, regarding mobile dev, “… but without vendor blessing, they aren’t likely to get a lot of traction” misses the mark. What’s needed are a few success stories of people writing solid Android apps using JRuby and people will follow along. There’s a lot of diversity in the tool-set for android dev and no compelling reason to do just what Google decides is The Way. I have no idea, though, if any version of Ruby is a plausible contender for iOS dev.
Also, thanks to Monkeybars and Rawr, easily distributable self-contained cross-platform desktop apps written in (J)Ruby are a snap.
Rails was the only game in town “for a few years”, i.e. 2005-2007. Of course things happen on the margins, and Sinatra came out of that margin and established itself as a unique and useful thing.
As to JRuby on Android, I agree with you to the extent that a killer app/framework combo built with JRuby could get a lot of people’s attention.
“As Ruby grew, it got a niftier way of doing object-oriented programming.”
I thought that Ruby was object-oriented from the start, and that it’s mainly how people have used it that’s changed. Am I mistaken?