(Bach’s article speaks directly of software testing practices, but it’s all applicable to other development practices as well.)
Ted Neward has rediscovered Lisp and noticed the similarity between many of Lisp’s strengths and some of the stuff he’s been hearing about Ruby. And he’s right. Yes, Ted … Ruby’s a great candidate for building DSLs.
I’ve been particularly interested in this, watching the Ruby community over the past two or three years learn to use the language in this way. I first encountered this style of Ruby programming almost four years ago, with Mathieu Bouchard’s Ruby X11 library, which starts by defining a DSL for specifying X protocol packet formats. Since then, other Ruby developers have come to understand the power of this technique, and are learning how best to use it.
If you use Rails, for example, you see immediately how Ruby has been augmented from within to be a DSL for specifying relational mapping, web application component relationships, validation criteria, URL-to-page mapping, and several other things. I’m preparing a talk explaining how to do such things in Ruby. But one of the most important things to know is that it wasn’t done in a vacuum … it was done in the context of building a real application, Basecamp. That’s the way frameworks, including DSL-based frameworks, should be built. In the the introduction to Paul Graham’s other book, he writes:
You don’t just write your program down toward the language, you also build the language up toward your program. Language and program evolve together. Like the border between two warring states, the boundary between language and program is drawn and redrawn, until eventually it comes to rest along the mountains and rivers, the natural frontiers of your problem. In the end your program will look as if the language had been designed for it. And when language and program fit one another well, you end up with code which is clear, small, and efficient.
That quote doesn’t make much sense to Java or C# programmers, because in those languages the ability of libraries to extend the language itself is limited. But in Lisp, Smalltalk, or Ruby, library design really is language design.
As I prepare my talk, I’ll try to blog more about using Ruby for DSLs – how to do it, why Ruby is a good language for that style of programming, and what its limitations are.
(Oh, and Ted … the night before you bought your book, I also bought a geeky book while on a date with my wife. You and I are scarily alike, my friend.)
Sherlock is one of Apple’s OS X applications that never really lived up to the hype. Once featured prominently in every OS X demo and brochure, it has all but vanished … you have to poke around for a while on Apple’s site to find any mention of it at all.
One of the things that came along with Apple’s new product announcements yesterday was an updated set of preview pages for Tiger, the next version of OS X that’s due out in a few months. No mention of Sherlock, not that anyone should be surprised. But what struck me was the new info about Dashboard. They’ve added some new widgets to the lineup. Stocks. Yellow Pages. Dictionary and Thesaurus. Language translation. Flight tracking. A friend who watched the keynote told me that Steve demonstrated a prototype widget from eBay.
Where have I seen that lineup before? Oh yeah! In the Sherlock toolbar.
Dashboard is the new Sherlock.
That’s fine as far as it goes … but will Dashboard fare any better than Sherlock? (I won’t discuss their similar origins.) I think Dashboard solves most of the problems that harmed Sherlock:
- It’s reportedly fast; more to the point, it’s meant to run all the time, letting you get in and out quickly.
- The interfaces are dazzling. Sherlock’s interfaces may not have turned people away, but they weren’t great enough to fuel either user or developer excitement.
- In one sense it’s still an integrated app, but (from what I can tell) it won’t have that feel to the user. You get the widgets you need, and that’s it.
- The widget development model is much nicer, and is already attracting a lot of interest from developers.
I always thought Sherlock was a cool idea with an implementation that didn’t make the grade. I look forward to using its successor.
The Ruby programming language is popping up everywhere this week. This is yet another in a series of indicators that something’s brewing in the programming language space.
First, on Monday, Mike Loukides blogged about almost trying to learn Ruby. It’s fun to see that he’s at least planning to learn Ruby. At JavaOne a couple of years ago, Mike told me that O’Reilly really wasn’t seeing much interest in Ruby. I replied that Ruby was still at the stage where the “thought leaders” were discovering it. By Tim O’Reilly’s own heuristic, where the alpha geeks are going, others soon follow, and I predicted that Ruby would soon become more popular. I know that O’Reilly’s seeing at least one indicator of increased Ruby interest, and maybe that’s one reason Mike’s planning to learn Ruby. This time, though, he decided he could get things done much faster using the tried-and-true Java way, and left his copy of PickAxe on the shelf.
Even though he decided not to actually try Ruby, he’s questioning whether it’s really useful. That’s not an auspicious start for Ruby this week, I guess. But back to Mike later.
Today, there are a couple of other things. (And if you average Monday and Wednesday, you get Tuesday, see?) First, Howard Lewis Ship (author of the best Java web framework) showed up on ruby-talk and also posted a very favorable blog about his first Ruby program. I was elated to see this. Howard’s expressed skepticism about dynamic languages to me at an NFJS conference, and was obliquely dismissive of Ruby in an earlier blog. But he’s tried it, and was really impressed. I like the way he describes his first Ruby program: “My trembling first journey into Ruby is […] sloppy, doesn’t report errors well, and took me too long to write (almost as long as it would have in Java!)” His first program in a new language, and his criterion for “took too long to write” is that it took nearly as long as it would’ve taken in Java. Sounds like Howard caught a glimpse of how productive Ruby can be once you know it well.
And I have to say that Howard’s first program is very nice! There are some things in it that an experienced Ruby developer would do differently, but it’s definitely not “a Java program written in Ruby.” Clearly Howard tried to learn not just the syntactic details of Ruby, but “the Ruby way.” That’s how we should all approach learning a new language.
So back to Mike Loukides. Maybe Ruby just isn’t right for Mike. I’m on record saying that, in the debate between static and dynamic typing, perhaps there’s not “one true way.” But I’m convinced that for most tasks, dynamic languages are the way to go. (And I was a Java bigot for quite a while!) It’s instructive to draw some lessons from the contrast between Mike’s and Howard’s experiences (and I’ll throw in a few general thoughts, too):
- Anytime you have learned one programming language really well, you’ve reached a kind of “local maximum.” To learn something different, even if it’s ultimately more powerful, means stepping down from your current peak of familiarity and expertise and flailing around like a newbie on ice skates for a while. You won’t see the benefits instantly. Howard describes his “trembling first journey,” and that’s how we can expect to feel the first time we try to write in a new programming language.
- Until your project is big enough that the gains start to outweigh the cost of the learning curve, the new language is bound to seem like a net loss. Howard’s 292-line Ruby program is about the smallest project where you could expect the effort to pay off. (After all, it took almost as long as writing it in Java! :-) Mike’s 25-line Java program is definitely too small.
- There are tradeoffs in languages, and Mike’s right: not declaring your variables means that you don’t have quite as much help debugging misspelled variable names. But the payoff comes in other ways, and not all of them have to do with writing the production code. Ruby_does_ make writing the code easier, I think – but it also makes it easier to write tests, and the code is easier to change.
- Not all “scripting languages” are alike. Mike implicitly criticizes the terseness of Perl (and also the “cryptic esthetic” of Perl culture, I suspect) when he lauds Java’s readability. But Perl is different from Java in many ways, and Ruby only shares some of those characteristics with Perl. The Ruby language and the Ruby community place a big emphasis on readable code.
My intent isn’t to bash Mike Loukides; he’s a great guy, and he definitely has a point: the overriding criterion is getting the job done, and for his recent purposes learning a whole new language was probably overkill. (And besides, it would be the height of foolishness to bite one of the hands that invited me to Foo Camp.) But I do hope he’ll make time to give Ruby a try, and give it a chance to prove itself on something reasonably sizable.
(Oh, and the other thing about Ruby that happened today? I noticed that, on the very cool website 43 Things, “Learn Ruby” is number four on the list of most popular things people would like to do. I wouldn’t read too much into that; I learned about 43 Things through the Ruby community, and I suspect that high placement is an artifact of the way word of the site has spread. But it was still a pleasure to see.)