Thursday, May 07, 2009

Diamondback Ruby Interview

After the announcement of Diamondback Ruby on ruby-talk a bit ago, I decided to contact the developers to learn more about what they're doing. Two of the team members, Mike Hicks and Mike Furr, and I ended up having quite a conversation that I'm posting as the interview below.


What do you hope to learn from this project?

Mike Hicks There is a long-discussed tension between statically (or explicitly)-typed languages like Java and dynamically (or implicitly)-typed languages like Ruby. My hope has been to discover how to include the best aspects of static and dynamic typing in a single language. We all really like Ruby's design and features, and felt it was the right language to start with. As we go, we'll look to derive general design principles that make sense for most any programming language, to simplify and improve the process of programming generally.

Static types are useful at catching bugs early, and serving as useful documentation (indeed, RDoc includes a pseudo-type for Ruby library methods). But static type systems may reject perfectly correct programs due to their imprecision, and thus can "get in your way," particularly when doing rapid prototyping. On the other hand, dynamic types suffer no imprecision, but delay discovery of some bugs until run-time. It can be particularly annoying to mistype the name of a method in a call deep within your complicated program, and have the program fail after running for a long while with "method not found," when having a type checker would have immediately revealed the mistake. The challenge is to incorporate the best bits of both approaches, e.g., to not reject programs prematurely (as a static type system could) while finding as many certain errors in advance as possible.

Mike Furr We had two main hypotheses going into this research. The first hypothesis was that development in dynamic languages doesn't scale. This is a hard thing to measure, but there is a fair amount of anecdotal evidence that seems to support this. For example, just recently a few of the Twitter developers were interviewed about moving their infrastructure from Ruby to Scala, and static typing was mentioned as one of their advantages of Scala over Ruby.

The second hypothesis we had was that most people "think in types" even if they don't write them down while programming. Thus, we imagined that most code written by Ruby programmers would be accepted by a sufficiently advanced static type system. Thus we hoped to be able to design a type system for Ruby that was powerful enough to handle the kind of Ruby code people actually write, but not be so complex that it was impossible to use.

What made you choose Ruby as your test implementation instead of Python, Perl, or one of the other widely used dynamicly typed languages?

Mike Furr When we were first throwing around ideas about analyzing a scripting language, Ruby seemed to be the language with the most momentum, likely because of the release of Ruby on Rails a few years earlier. Ruby is also a rather young language and its syntax and semantics are continuing to evolve. Ideally, we hope that our research could influence future directions for Ruby, although much of our research would be applicable to other languages as well.

Mike Hicks I really like Ruby's design, particularly the principles that "everything is an object" and "duck typing." We also liked that Ruby was the core of Ruby on Rails, whose popularity was increasing. In our exploration of Perl, an early contender, we became frustrated with the huge number of overlapping language features, and quite surprising behavior in many instances. We didn't see how to write a useful static analysis for Perl programs without a lot of difficulty. We thought about Python only cursorily, and I don't recall any particular downsides that came up.

Why did you choose OCaml as your implementation language?

Mike Hicks Our group at Maryland uses OCaml almost exclusively for writing static analysis tools, particularly for analyzing C code, so it was natural to want to use it for this project, too. OCaml, in my view, is the perfect language for writing a compiler or analysis: its syntax is terse (as compared to Java, say), and features such as first-class functions and pattern matching very much simplify the process of writing tools that analyze or manipulate structured data, like abstract syntax trees. We followed the lead of the CIL (C Intermediate Language) project, also written in OCaml, in designing RIL (Ruby Intermediate Language), the core of DRuby. For example, both CIL and RIL syntax trees are simplified after parsing to make analysis more manageable.

Mike Furr OCaml is my favorite language to program in and I have been using it throughout my time in graduate school. However, I also think it is the right tool for the job. The quintessential example for functional programming languages is writing a compiler, and DRuby is essentially a compiler front-end. OCaml's type system is also a real asset in developing a complex code that manipulates abstract syntax trees.

A lot of folks seem to think that you've written a Ruby implementation in OCaml instead of a type analyzer for the existing 1.8 Ruby. Do you think an OCaml implementation of the language would be a good thing? Why or why not?

Mike Hicks This is a hard question to answer. Why might one want to implement an interpreter in one language vs. another? I can imagine several reasons: performance, portability, maintainability, and reliability, among others. Developers often implement interpreters or VMs in C/C++ for reasons of performance and portability. But C and C++ encourage programming "on the edge of safety," so mistakes can lead to crashes, security vulnerabilities, etc., hurting reliability and maintainability. By contrast, coding in a high level language, e.g., Java or OCaml, avoids many reliability problems, thanks to type safety and garbage collection, but at the cost of some performance. (For grain-of-salt interlanguage performance metrics, check out the Computer Language Benchmarks Game, http://shootout.alioth.debian.org.) And the language is really well-suited to writing compilers and interpreters, thanks to its rich structured datatypes and pattern matching. In my experience, an OCaml-based compiler or interpreter is much more succinct than one written in Java. So I think it's a good option.

Mike Furr There are already several implementations of Ruby available and so adding another one simply because it was implemented in OCaml doesn't seem like a good idea to me. Maintaining an implementation of Ruby is a lot of work since the language continues to evolve its syntax and semantics from version to version and the API of Ruby's standard library is also tied to particular Ruby versions. Instead, there would need to be a fundamental new feature that an OCaml implementation would provide that developers would find useful. For example, it might be interesting to explore compiling Ruby programs to native code using the OCaml bindings of LLVM and doing type driven optimizations based on Diamondback Ruby's type system. This would be a lot of work and I have no idea if the resulting code would be any faster than some of the newer Ruby virtual machines, but it could be a fun project.

How does static type inference affect the balance between testing and debugging? How does it affect the testing and debugging processes?

Mike Hicks Type inference is a debugging aid, I suppose. It is meant to help identify bugs that could come up, and do so without requiring you run your program. It is not a replacement for testing, though. Essentially it finds out whether you are programming with a certain level of consistently; if in one place you declare your method to take three arguments but elsewhere call the method with four, that's an inconsistency. But it doesn't prove that your code does "the right thing," e.g., whether you formatted your output string correctly. You need tests for that. Our approach allows one to help the other. When you write tests, DRuby will profile their execution to provide information that helps type inference. And type inference helps you identify some bugs without having to run tests.

Mike Furr Static typing is a tool just like testing frameworks and debuggers. All of them are meant to improve the quality of the software being developed, and each has their own advantages and disadvantages. The major advantage of static analysis is that it is able to reason about every path through your program simultaneously (and before it is run). Static types also provide terse, verified documentation. If you method has a type annotation that says it returns a Fixnum, that annotation will never become stale and can be trusted by any other developer who is calling your method.

However, static typing isn't perfect and is not meant to replace other QA techniques such as testing. One of the goals for DRuby is to allow programmers to incrementally add static types to their code bases, allowing them to benefit from extra checking where they want, without requiring changes to the entire code base.

You mentioned that you've found several potential errors in Ruby libraries and prgrams as a result of type inference analysis. What kinds of problems are you finding? How could the Ruby community take advantage of these kinds of discoveries?

Mike Furr The Ruby community has accepted test driven development as a standard practice and so we didn't expect to find a large number of errors. However, getting 100% testing coverage is often difficult and, not surprisingly, many of the bugs we found were in error handling code that was not exercised by any test cases. Some of these bugs were extremely simple, like misspelling a variable name, or referencing a method that did not exist.

One bug that I found particularly interesting was where a program called a method in the "File" class that didn't exist. This code was covered by the test suite and didn't cause a test failure. The reason for this was because the testing code monkey patched the File class to add the method before running the test suite. Thus, you would only encounter the problem if you executed the code outside of the test suite.

We hope that DRuby will develop into a tool that developers can run on their projects as part of their own quality assurance process. In the mean time, we have been filling bug reports for the errors we discovered so that the authors can fix them. For example, we found 2 errors in the Rubygems package manager that have already been fixed in their latest release.

What kind of feedback are you getting from Rubyists?

Mike Furr We've gotten some very encouraging feedback so far. In fact, despite the legendary flame wars between static and dynamic typing, I haven't received any negative comments about the idea of bringing static types to Ruby. A lot of people are using Ruby these days and so a tool that can help improve their development process through finding bugs or improving documentation is clearly appealing. Diamondback Ruby still needs some polishing so that programmers can begin using it on their own projects, and this is something we are going to continue to work on. Eventually, we'd like to perform some user studies to measure the effectiveness of the various features of Diamondback Ruby, and so its usability is certainly important to us.

How well do Ruby programs perform under Diamondback Ruby?

Mike Furr Diamondback Ruby uses a combination of static and dynamic checks to ensure that Ruby programs are well typed. Programs that can be checked purely statically (which we hope will be most of the time) will have no overhead at all since the programs can be safely run by a traditional Ruby interpreter unchanged. However, if the program does require a runtime check, then individual objects or methods may be instrumented to ensure they don't violate their types. When dynamically checking objects, we instrument the eigenclass of the individual object so that only methods calls to that object must be checked (not every object of the same class). Thus the checks are pay-as-you-go: the more objects that require dynamic checks, the higher the overhead. Therefore, it's hard to use a single measurement to quantify the overhead as it can vary from execution to execution of an application. I have run some micro-benchmarks and observed a 15% slowdown in one case, but this data point should be taken with a grain of salt, as it was merely to convince myself that the instrumentation was working and not egregiously slow. An application that rarely uses a dynamically checked object may see almost no overhead, but if the application calls methods on that object in a tight loop, it could be significantly higher.

Are you using the RubySpec framework to drive your implementation?

Mike Furr DRuby includes a dynamic analysis that allows us to reason more precisely about features such as eval(). This analysis requires us to parse the original Ruby program into our intermediate language, add any instrumentation code, and then write the transformed program out to a separate location on disk to be executed by the Ruby interpreter. This whole process was rather tricky to get right, and we used the RubySpec test suite to ensure that our transformations were correct. It was definitely a great help to have such a comprehensive test suite.

We haven't used the RubySpec tests to drive any type analysis for the standard library just yet, but I can definitely see using it in the future as we continue our research.

I'd really like to see OCaml get more play, but I keep seeing books like this and wonder when a good OCaml book for non-Math/CS types is going to hit the shelves. What will it take to get OCaml in front of more developers?

Mike Hicks My observation is that languages take off when library or framework support for some important set of applications hits critical mass. Then developers interested in that application intuit that it's easiest to build that app in a certain language or framework, and then go off and learn what they need to learn. Then those developers start building more libraries and the language is used for other things. I think we can see this trend in Perl (first killer app: text processing), Java (first killer app: applets), Ruby (first killer app: Rails), etc. We're starting to see more adoption of Erlang, thanks to the rise in multi-core and high-availability commercial systems, and we're seeing a growth in Haskell, at least in part because of all of the code you can get for it (though I can't speculate on what its killer app is).

When I first started doing work in static analysis, C/C++ were the languages of choice, oftentimes building on gcc or other existing tools. But then George Necula and his students wrote CIL (C Intermediate Language). Nowadays many, many tools are written using CIL as the front end and intermediate language, by people who never were "functional programming people." CIL was just so much better, clearly, than anything else, that people flocked to it. (As of today there are 297 citations to the CIL paper, according to Google Scholar — esp. noteworthy for an "infrastructure" piece of work.)

Of course, C analysis and other "symbolic computations" on programming languages are a niche area, and not likely to bring in the masses. OCaml still needs that breakthrough use-case of great interest that will push it over the top. It remains to be seen what that will be. But once it's found, the books, tools, etc. will all follow.

Mike Furr I agree with everything that Mike (Hicks) said but would also add that OCaml needs to overcome its branding as an "academic language". I have found that a lot of programmers think of functional programming as a fringe concept, perhaps invoking bad memories of struggling with it as an CS major. At the same time, one of the features people really seem to love about Ruby are blocks, which of course are a functional programming technique. I think that Ruby's syntax plays an important role here: programmers don't have to understand what a higher order function is to be able to use a block and yet they can immediately see the usefulness of the technique. However, a functional programmer might find this syntax restrictive (why only one block per method?). Perhaps the road to OCaml's adoption will be through Ruby which gives a gentler introduction to some of the same ideas used in ML.

Click here to Tweet this article

Wednesday, May 06, 2009

MWRC Interview Collection

I've done a bunch of interviews ABOUT MWRC. Some of these have been quite popular, while others are sort of hidden gems. If you've enjoyed one of them, maybe you'd like to see some of the others. I'll start out with three of my favorites, but there's a complete list down below.

1) My interview with Philippe Hanrigou has become one of the most popular posts on my blog. He has developed a reputation as one of the great MWRC speakers, and I think his interview is a good indicator of why. You might also want to see his talks on What to do when Mongrel stops responding (from 2008) and What The Ruby Craftsman Can Learn From The Smalltalk Master (from 2009).

2) I started an interview with David Brady on twitter. Before it was over, Kirk Haines and Jim Weirich had joined in. Not only did this interview spawn a great meme, the story got better when David came into the second day of conference from his sickbed and gave his talk during lunch (we'd already run the replacement talk). Now that's dedication. You should go watch David's presentation on TourBus, Kirk's, on vertebra, or Jim's keynote.

3) I like this last one because it provides a different take on things. I interviewed Josh Susser about his interest in attending MWRC. Maybe most telling about his interest was that he went off and organized GoGaRuCo (hmmm, isn't there something about imitation and flattery — just kidding, Josh and GoGaRuCo are great!).

MWRC 2009


MWRC 2008

Questions Five Ways, an introduction

Next week, on Wednesday, I'll be starting a new feature here at On Ruby, Questions Five Ways. I asked a friend of mine, Andrew Young, to put together a small graphic that I could use for these posts. I really like the way it turned out.

The idea is that I'll invite five different hackers to join a conversation centered around a guiding question. Once we've had a couple of days to kick things around, I'll summarize the discussion and post it here.

Hopefully the discussion won't stop just because I've posted it here. I'd love to see it open up and blossom with a wider audience, so please add your thoughts in the comments each week. If you'd like to follow along at twitter, let's use the #q5w hashtag.

I've got a bunch of questions, and a number of potential victims, err, participants in mind.

Just to whet your appetite, here are a couple of the questions I plan on asking:

  • What is the right interplay between testing code (unit test and the like) and code analysis (lint, reek, and their ilk)?
  • What kinds of activities are most important to building (or keeping up) a healthy users group?

I'm sure I don't have a corner on good ideas though. If you'd like to share your requests below, I'll try to work the best of them into the cycle.

Click here to Tweet this article

Monday, May 04, 2009

RubyNation Mini-Interview: Hal Fulton

RubyNation (June 11-13 in Reston, VA) is coming up pretty quickly, and I've started a series of mini-interviews with speakers and organizers there to help people get a feel for what RubyNation is going to be like.

If you're interested in getting more that this little taste, I'd recommend that you go register soon. I don't think the seats are going to last long.

My first interview is with Hal Fulton (@hal_fulton). Hal's been involved in the Ruby world for a long time. He's the author of The Ruby Way. Hal currently does Ruby work for Collective Media.


What makes regional Ruby conferences special?

Hal For one thing, a regional conference always puts its own spin on the whole event. It's organized by local people and tailored to their own personality and environment, so it has a different flavor from the international conference.

Second, you get to meet people and hear talks that you wouldn't otherwise. A lot of these people have never made it to the "big" conference. It's great to realize that there are numerous Rubyists out there who are interesting, creative, and competent -- and you may never have heard their names before.

What makes RubyNation stand out as a regional Ruby conference?

Hal I've met several people from the area, and I think it's a definite hotspot of programming talent.

Additionally, the area itself holds a certain fascination for me -- the land of Thomas Jefferson, very near the nation's capital. I am a bit of a Jefferson fan, and in spite of everything I've always liked DC -- I was a page in the House when I was sixteen.

Other than your own talk, what are you most interested in seeing at RubyNation this year?

Hal I look forward to them all, in particular David Alan Black's talk on Ruby 1.9 -- David is an old friend, very competent and knowledgeable, and one of the earliest adopters of Ruby in the US. And of course we all have things we haven't learned about 1.9 yet, or at least things that haven't sunk in and become instinctive.

I'm not a Rails person, nor a web person in general. That said, I do look forward to Yehuda's talk -- I think Rack is a small masterpiece, and we can learn from it. Also David Keener's talk on RESTful web services catches my eye.

Your talk is on Reia, a Ruby-like language implemented on the Erlang VM. What attracted you to this language?

Hal I've played with Erlang a little, and I've seen its power. I've also seen its diffficult syntax and its overall paradigm which is (to many) bizarre and "inside out."

Reia seems like a very interesting compromise -- much of the "under the hood" power of Erlang blended with the expressiveness and flexibility of Ruby.

I think as we move closer to "real concurrency," these kinds of techniques will lead to a big leap forward in the way we write software.

What kinds of things are you using Reia for?

I'm not "using" it yet, and I'm not sure anyone is really. Let's say I'm very intrigued by its potential, and I'm studying it and playing with it.

Are there other Ruby or Ruby-like implementations that you've got your eye on?

Hal I try to keep "some" watch on all of them -- unsuccessfully of course.

For me, Matz's implementation is still "the" Ruby and will be for the foreseeable future.

But I'm also very interested in Rubinius. I haven't really touched it yet, but I do want to if I can find the time.

I haven't played with JRuby really, but I'm glad it's out there as an option. It's an important project.

Also Dave Thomas has some brilliant ideas for experimental variants of Ruby. I'd love to see some of those implemented, even if only as proofs of concept.

Click here to Tweet this article

Author Interview - The Well-Grounded Rubyist

Now that Manning has released The Well-Grounded Rubyist by David A. Black, I wanted to sit down with him and talk a bit about his new book.

His Ruby for Rails set an awfully high bar as the book that really explained Ruby to Rails users (and everyone else). The current title has been called a "reworking" of the former to remove the Rails bias.

Hopefully this interview will whet your appetite for David's new book.


Ruby For Rails has been one of my favorite Ruby books since it came out. I'm really excited that The Well-Grounded Rubyist is coming out in a matter of weeks. What do you think is the best thing about your new book?

David The title! Well, not really, but I do love the title, if I say so myself. (In case anyone's wondering: I did take inspiration from "The Well-Tempered Clavier".)

As for the material and the content: I have always found it gratifying when readers single me out as someone who can explain things clearly and in depth, and I believe TWGR delivers in that area pretty much throughout. I spent thirteen years as a full-time teacher, and I've been writing all my life. I love helping people understand things, and that's what I've worked most diligently at doing in this book.

You call your new book a repurposing of Ruby For Rails. How do you approach Ruby differently when writing for a Ruby developer rather than a Rails developer?

David To a large extent it's a question of the topic coverage. TWGR maintains, I think, very much the same "voice" as R4R, and addresses the reader at the same level. But the topic coverage has changed a lot — and not just because Rails has been taken out. There's material in TWGR on threads, sockets, sets, encoding, enumerators, and more, none of which were in R4R, and greatly expanded coverage of other built-in functionality include file I/O, ranges, system command invocation, and others.

Selecting topics was a big part of writing R4R, since the whole point was to write a Ruby book that was "optimized" for a certain readership. And as I started thinking about TWGR, I realized that careful, creative topic selection was important for a "just Ruby" book too. I wasn't setting out to write a complete language reference, so the process of deciding what to include loomed large.

You take a pretty different approach to explaining Ruby than most other authors/speakers. What do you think makes your approach work so well?

David Typically, introductions to class-based object-oriented languages, including Ruby, start by talking about classes, and then bring objects into the picture as instances of classes. I look at it the other way around. The object is the fundamental unit of meaning in Ruby, so why not start with that?

Furthermore, I like to put object dynamism on the radar very early — the fact that objects are not constrained to the abilities they derive from their class but can take on behaviors of their own. Of course most Ruby developers don't spend their days writing


 def dog.bark
and such. But I do believe that if you learn about objects and their life-cycle first, and then look at classes as a kind of convenience macro for spawning objects, your knowledge of Ruby will build smoothly from there, and you won't think that object-specific behavior is a blemish.

A lot of publishers are opening up the book writing process these days. How much did Manning's MEAP affect your book?

David I'll do a bit of soul-searching here, if I may. I'm a very territorial writer. I don't like the idea of leaving a paper trail showing what I later decided to change or fix or improve; I think of writing as a basically closed-door artistic process, and just as I don't want people listening in while I'm practicing the cello, my instincts run strongly against releasing unfinished written work.

I have, nonetheless, tried to get into the spirit of the open-process era, because I think it's been proven effective for technical writing and because I know that a lot of my territoriality comes from my temperament rather than from concern about the final product. Besides, even without the MEAP, the manuscript is sent out to a body of twelve or fifteen outside reviewers at three points along the way — so the "closed door" isn't all that closed anyway!

So I've participated in the MEAP, probably not plunging into it as fully as some authors do but trying to meet it at least halfway, even if it means leaving (or, perhaps, expanding) my own comfort zone. I think the book has benefited from it.

So far, you've had your hand in books, videos, conferences, and training. What does the future hold for you?

David Don't forget programming :-) As for the future: I've started working on a book for the Pragmatic Bookshelf, entitled "Rails Choices". It's a guide to how to think about and make sense of the many possible choices (and it's an increasing number, as we get toward Rails 3) that face developers and project managers when they're starting a Rails project: everything from which version of Ruby to use to which templating system to which session storage mechanism. I'm not going to try to cover every possible choice; I'm sticking to the out-of-the-box defaults plus a select handful of proven, popular alternatives. I want to get beyond the personal preference level, and help people examine the needs and priorities of their specific projects, and make choices based on that.

In general, I'm finding my multi-faceted Ruby-oriented life very rewarding and enjoyable, and I'm hoping for more of the same.

A lot has changed in the Ruby world since R4R, which of those changes are you most happy about?

David I'm happy about the fact that Ruby is in much wider and more prolific use, and that we have so many books and events. (I don't think any other language has as vibrant a world-wide conference culture as Ruby.) It's also great to see that the "What's this 'Ruby' thing?" syndrome among Rails developers has dwindled; just about everyone seems to understand from the outset how Ruby and Rails related to each other (and if R4R helped bring that about, I'm delighted).

I'm excited about the new Ruby implementations — JRuby, Rubinius, and others — and the coming-of-age of Ruby 1.9. As everyone knows who's followed along, the path to 1.9 has not always been smooth, but 1.9.1 is stable (that's the version the book addresses) and as I've delved into it more and more deeply, I've been more and more impressed by it.

Which ones impacted The Well-Grounded Rubyist the most?

David I choose:
(e) All of the above!

It's true actually. The wider adoption of Ruby is largely responsible for my enthusiasm about writing the book. The way the Rails world has come to terms with Ruby, to the mutual benefit of both, made me realize that a general Ruby book could also be "for Rails", in the sense that many Rails developers are eager to learn as much about Ruby as they can, whether every bit of it pertains directly to the bulk of their Rails work or not. The new Ruby implementations don't enter into the book directly, but it's hard not to feel inspired by that work, and many discussions surrounding implementations have touched on topics in ways that have probably affected TWGR.

And Ruby 1.9 — that's the main event, the major impetus for writing the book. It's been hard, because things have been changing a lot. Sometimes I'd write an example and then discover a few weeks later that the wording of some error message had been altered, or that something had shifted in the core class hierarchy. (I'm thinking specifically of Enumerable::Enumerator becoming just Enumerator.) It's been a moving target at times; but all the more thrilling is it for the book's timing to be such that it can address a stable 1.9 version while there's still a lot to learn and a lot of excitement.

What do you see happening in the Ruby world over the next year or so?

David Very hard to say — which is probably good, since it keeps it interesting. I think that Ruby 1.9 will achieve a lot more penetration. And we're seeing a lot more Ruby implementations, some based on the Matz code and some not. I don't just mean JRuby and Rubinius, but MacRuby, Ruby Enterprise Edition, MagLev, and others. I suspect we'll start seeing specialized subsets and forks of Ruby that aren't necessarily compatible but that are "Rubies", the way different LISP dialects are "LISPs". I think Diamondback Ruby is in that category, though I haven't looked at it closely.

In any case — here's hoping we have many more years of Ruby practice, experimentation, collegiality, and productivity. It's certainly been fun so far!

Click here to Tweet this article