Michael Feathers just put up a blog post on a topic that’s near and dear to my heart: Ending the Era of Patronizing Language Design. I can’t resist chiming in. (This post might be more interesting if I disagreed with him on some point, but I just don’t. I just want to emphasize some of Michael’s points and offer some supporting anecdotes.)
Michael writes, “For years, in the software industry, we’ve made the assumption that some language features are just too powerful for the typical developer—too prone to misuse.” I’ve heard that argument many, many times, from people I strongly respect. And for a long time I believed it. For several years after I became enthusiastic about Ruby, I worked in places where most of the developers were typical, average programmers, and I refrained from really pushing Ruby in those environments because I thought Ruby was too powerful for them.
Then, a few years ago, I spent some time in a role where I was doing architectural reviews of IT projects (mostly Java projects). And one day I came to a shocking realization: there’s no way those projects could have been screwed up any worse if they had been written in Ruby.
What was alarming and depressing about those Java projects I was reviewing was not that they were poorly designed. I expected that; design is, after all, difficult. No, the surprising thing was that somehow, against all odds, the developers had managed to wrestle these monstrous designs over the finish line. The sheer dogged determination it took to do so was impressive and horrifying. I would have given up in despair long before.
The experience taught me a valuable lesson:
Weak developers will move heaven and earth to do the wrong thing. You can’t limit the damage they do by locking up the sharp tools. They’ll just swing the blunt tools harder.
I’ve been working full-time in Ruby now for almost four years. Everything I’ve seen while working on Ruby projects confirms what I realized back then, and it matches what Michael wrote about the ethic of responsibility that a powerful language like Ruby fosters. Ruby isn’t a panacea. The weak developers will wreak havoc in Ruby projects as well. But I think Ruby also makes it more difficult to hide from those mistakes without learning something from them. Yes, many Ruby projects have design weaknesses, but the usual standard is better than what I’ve seen in other languages, not worse.
If you want your team to produce great work and take responsibility for their decisions, give them powerful tools.
Thanks to Kresten for organizing the fun conversation and posting it!
Like Chad, I think MagLev’s initial performance numbers will hold up. It’s possible that as it matures it will get slower, but it could get a lot slower than it is now and still easily be the fastest Ruby VM around.
And I agree with Chad that it might even get faster. I’ve also spent some time investigating how to make Ruby run on a Smalltalk VM, and it’s a really close fit. During the presentation at RailsConf, either Avi or the Gemstone guys revealed that they had modified their Smalltalk VM by adding two new bytecodes aimed at Ruby. I’ll go so far as to speculate: it’s likely that those two bytecodes deal with variadic methods and creation/lookup of dynamic instance variables. It sounds as though the core Ruby language is nearly complete on top of that base, so it’s easy to imagine that the early, hurried implementation of those two new bytecodes could be optimized further. And some of the Ruby features that have hurt JRuby’s performance will be no problem on a Smalltalk VM—ObjectSpace, for example, can work using the same facilities that Smalltalk’s development tools use today.
The persistence story is amazing. Avi and the team at Gemstone plan to implement an interface that is similar to ActiveRecord, but cleaner, since the object/relational impedance mismatch no longer applies.
Finally, there’s the question of licensing. I’ll be shocked if MagLev is open-source, but I think there’s room for a proprietary Ruby implementation. The team has committed to complying with RubySpec, which means I’m not very worried about compatibility.
Most Ruby projects won’t need MagLev, but the ones that do will gladly pay for a top-notch, supercharged implementation with great scalability and persistence stories.
I’m definitely looking forward to hearing more about MagLev over the next few months.
I’m so glad Avi Bryant jumped into this discussion. (I was hoping he would.)
The story so far (for the probably 99% of my readers who don’t read a lot of Smalltalk blogs): Avi and I had a discussion last year at OSCON about Ruby and Smalltalk, and Rails and Seaside. Avi was once a Ruby guy, but switched to Smalltalk (but he’s still friendly to the Ruby crowd). I’m currently a Ruby and Rails guy, but I’ve evangelized Seaside rather extensively.
During our discussion, we talked about the different tradeoffs that the two communities make.
I related that story to Neal Ford, which helped him to understand some things he’d been wondering about, which led to these blogs. In a vastly oversimplified nutshell: Ruby has some strengths that Smalltalk is missing, because it gives you a place to put all your stuff. (Please note that this does not imply that Smalltalk is fundamentally inferior to Ruby. I believe Smalltalk, in turn, has other strengths that Ruby is missing.)
James Robertson took issue with Neal’s blog, but gave no real evidence to back up his point. I was getting a bit frustrated with the “all heat and no light” nature of the discussion, until Avi saved the day by explaining the Smalltalk way of doing things.
I have to say that I think to some degree Avi confirms Neal’s and my point: Ruby provides a ready-made place for stuff like “has_many”, whereas in Smalltalk, to provide similar functionality while preserving the “statement of intent” (as we’ve been calling it) the tool has to build a place for that statement. Which is fine, but it seems to me that “to make the generated code round-trippable,” as Avi says, adds extra complexity to building such tools.
Again, this is not to say that the Ruby way is necessarily superior. These different approaches reflect different tradeoffs. That’s the conclusion Avi and I reached during our chat last year, and we were both happy to agree to disagree. Smalltalkers tend to prefer generating the methods directly, because that way they can get the most value out of their terrific toolset. And Alan Knight (in his comment on James’ blog) definitely prefers generating the methods in-place, so that the full API will be visible to developers. We Rubyists, on the other hand, having generally crappy tools, are free to do things in a way that even rdoc doesn’t understand, and I for one like the fact that all those boilerplate methods aren’t physically cluttering up my source code. You pays your money and you takes your choice.
My interest in discussions like this is not to have a language war, and especially not between Smalltalk and Ruby. (There’s brother against brother for you.) The point is to learn from each other and, through learning about the other, to understand more clearly the strengths of both approaches.
Here’s another highlight from RubyConf 2007: watching Jamis Buck and Michael Koziarski give a terrific keynote based on their joint blog, The Rails Way. I leaned over to Alan Francis and mentioned how encouraging it is to see young programmers with a solid, confident grasp of design and development principles that I didn’t learn until I was much older. I don’t mean to embarrass either Jamis or Koz by this; I admire them greatly. They make me optimistic about the future of my profession. (And calling them young says more about me than about them, perhaps.)
It’s absolutely certain that the biggest factor in their early maturity as programmers is that they’re just very smart guys. I’m also sure they started programming at a younger age than I did.
But Alan and I think there’s a third factor: Ruby itself. Ruby helps to teach those good programming skills, and makes them easier to learn. I got the chance later to talk to Koz about it, and he enthusiastically agreed.
The first thing I said in my talk on Saturday was that Rails is like an instructional laboratory for how to build good software. I think that’s the thing I like most about Rails. A big part of that is Ruby itself. Ruby, its libraries, and its documentation are filled with examples of clean, well designed code, and Ruby makes it easier than most other languages to create clean code yourself. The community values and encourages it. Ruby teaches good programming by setting the goal, lowering the barrier, and providing a lot of assistance and encouragement.
I was thrilled last year when Chris Pine’s Learn to Program was published, and now _why has taken up the flag with his brilliant Hackety Hack. We should support efforts that are focused on using Ruby to teach children to program. I think it’s the best way available right now to grow a generation of great programmers.