Reginald Braithwaite-Lee really nailed it with a great post that ties together a bunch of my favorite topics into a nice, coherent bundle:
- language power and expressiveness
- why you sometimes don’t “get it” until you try something
- the different strengths of Rails and Seaside
I particularly like the way he debunks the “you can build new idioms in any language” argument: different languages have different idioms for building new idioms, and that makes a difference.
The first time I delivered my “Metaprogramming Ruby” talk at OSCON this year, I was privileged to have two of the masters of Ruby metaprogramming in the audience: Rich Kilmer and David Heinemeier Hansson. Rails is, of course, the poster child for the benefits of Ruby’s metaprogramming power at the moment. But Rich paved the way with several less well known projects that showed just how much metaprogramming power Ruby has.
Anyway, during the talk I presented two approaches to doing metaprogramming, and since Rich and David were there I put them on the spot and asked them to confirm my suspicions—and I was right. The two of them approach the task in different ways.
Rich typically starts with a domain he understands fairly well, and designs domain-specific constructs to support that domain. Then he implements those constructs using Ruby. That’s the approach he used during the week of OSCON to build the prototype of a Rails interface for his ActionStep framework.
I think that’s how most people think metaprogramming is done, and it sounds really intimidating and difficult—especially when you’re not used to thinking about domain-specific languages, or you don’t understand your domain very well yet, or if you’re not familiar with the techniques of metaprogramming.
But there’s another approach, and it may surprise people that DHH used this
different approach to design and build Rails. He admitted that when he
started building Rails he didn’t have a deep understanding of what a web
framework should look like, and he wasn’t an experienced Ruby developer. But
he started with a strong desire to build good, clean code, and a devotion to
the DRY principle as one way of keeping
his code and design clean. And then he “explored” his way toward Rails’
metaprogramming sweetness. During programming, when he found himself writing
duplicate code, or code that felt ugly or unnecessarily complex, he would
look for ways to eliminate the duplication or make the code simpler and more
expressive. Sometimes that was possible in ways that would seem perfectly
natural to a Java programmer. But in other cases he had to go farther,
augmenting the Ruby language itself through metaprogramming. In less dynamic
languages, some of that duplication or ugliness would’ve remained, simply
because there would be no effective way to eliminate it. (Don’t believe me?
Look at the source to
java.util.Arrays.sort.) But in Ruby your refactoring
toolkit is bigger, and most of Ruby’s metaprogramming idioms are quite easy
to use once you learn them.
That’s how I like to explain metaprogramming: as an additional set of tools that dynamic languages provide to help you eliminate bad-smelling code.
Those rich idioms give you a lot of power for keeping your systems clean and simple.
I enjoyed listening to the new edition of the Ruby on Rails podcast, consisting primarily of an interview with Avi Bryant, the creator of Seaside. I was delighted (but not at all surprised) to hear him give a lot of credit to Rails, and when asked about how to choose between Rails and Seaside, he gave an answer quite similar to my own.
It’s a nice interview; fight through the poor sound quality and give it a listen.
(This is a little overdue, but it’s been a crazy couple of weeks.)
I enjoyed reading Avi Bryant’s blog a few weeks ago about Mind Camp. He was delighted about getting a great compliment for Seaside from one of the Rails faithful: “I defy anyone to come up here and use any other framework to duplicate what we’re doing in Rails as quickly. Except Avi.”
That is certainly a great plug for Seaside, and well deserved. But Avi’s delight itself pays a great compliment to Rails; “Could anyone ask for a better plug?” asks Avi, and indeed praise from the Rails camp for another web framework is high praise.
Thinking of that reminded me of a few weeks prior, when I attended the Smalltalk BOF at OOPSLA. A Smalltalk newbie was there, and asked if Smalltalk had anything like Rails. There were snickers, and a few snide-ish responses of “better than Rails.”
I kept my mouth shut at the time, because it’s rude to show up to someone else’s party and upbraid them. But I think the question of whether Seaside or Rails is “better” is very much open for debate, and heavily dependent on your particular situation. (Disclaimer: I’m doing Rails work right now, but I’m a vocal fan of Seaside and have been introducing people to it in talks at NFJS symposiums for the past 14 months or so.)
Which brings me to the other incident Avi’s blog reminded me of. In early October, Daniel Steinberg sent me a note asking for “the 30-second reason someone would use Seaside and someone would use Rails.” Here’s what I wrote in response:
Seaside is much more advanced but not so mature. It contains core features that are well beyond what Rails can do, and those features attack some of the most difficult aspects of web development. Rails, on the other hand, has many, many more features that attack most of the many, many tedious and mundane aspects of web development [and some of the surrounding issues like packaging and deployment, database access, and testing], and it’s well documented, widely understood, and well supported.
So unless you are really comfortable with Smalltalk and/or are doing some very ambitious things with stateful web applications and complex control flow, choose Rails.
That’s overly simplistic, of course, but that’s what you get in 30 seconds. :-)
Oversimplified as it is, I think it’s a good summary. Seaside was starting to get some buzz at one point, and then Rails came along and (it seems to me) stole most of it, and I think there’s a reason for that. The reason isn’t that Rails is better – it is better in some ways, but Seaside is better in other ways. I think it’s just that Rails’ strengths address problems that are particularly frustrating to developers right now.
But there’s a funny thing about pain: when your worst pain goes away, it doesn’t take long to start being annoyed by the next worst. So it won’t be all that long before Seaside’s particular strengths start to look really attractive to developers who’ve grown accustomed to Rails’ niceties. And then it’ll be time for Seaside (or possibly some other continuation-based web framework inspired by it) to get the buzz again.
There are things Rails can learn from Seaside, certainly, but there are also thing Seaside can learn from Rails, and that learning will probably happen in both directions. As Avi pointed out in another blog this week, Smalltalk and Ruby are much more similar than they are different, so I see the two frameworks complementing (and, as above, complimenting) each other for some time to come.