Hacking gadflies

Java or Ruby in CSC 152?

In some recent correspondence with Wesley Beary 2005, I happened to mention that I have vaguely toyed with the notion of replacing Java with Ruby in CSC 152 at some point in the future. Speaking as someone who has now had some first-hand experience in writing applications in each language, he offered some opinions about the pros and cons of the replacement idea.

Here's how the conversation started. In an e-mail last April, in connection with a project he was working on, Wes wrote:

I am utilizing the opportunity to learn a number of new technologies. Some I'm sure you have heard of, but others are more obscure. I'm using MySQL for the database and Ruby for the CGI, with Rails (also called Ruby on Rails) as an intermediary and framework. I have found Ruby relatively easy to pick up, and Rails seems to provide a very nice framework to build database driven applications off of. Plus Rails uses a number of conventions and practices that make me do things the right way (or close), where I might be lazy otherwise.

I replied:

I've heard a lot of good things about Ruby and have written a couple of small system-administration utilities in it as experiments. At one time, I raised with the other computer-science faculty the idea of replacing Java in our 152 course with Ruby, so as to introduce students to the scripting paradigm as well as to object orientation. But after lurking on comp.lang.ruby for a couple of weeks, I formed the opinion that Ruby's designer suffers from a milder case of the mania that afflicts Larry Wall, the designer of Perl -- specifically, the delusion that any feature that lots of people want can be simply glued onto the existing language, regardless of coherence, intelligibility, or learnability. Ruby is just beginning to come into widespread use, but is already showing signs of bloat and mystification. One of the big lessons of the last twenty years of language design is that you can get away with bloat in libraries, even ones as vast as Java's, but bloat in the core language makes the learning curve so steep that you shut out the rising generation of potential users. Soon people learn only selected parts of the language, and if they learn different parts they can't read one another's programs.

He replied:

I would tend to agree that this is a threat. Whether or not it is enough to cause the learning curve problems I'm not really sure. I haven't had too much trouble picking up things as I go, but I have mostly stuck to the core libraries and functions, which are actually relatively short. How much additional stuff actually comes with typical distributions, I'm not sure. But over all I have liked the language pretty well.

I heard from Wes again today, and he has some new thoughts:

I've done some more thinking about Ruby as a language for teaching, possibly as a replacement for Java in the curriculum.

I think that both languages are useful, but I would not use them for the same things. If there were only two languages that were going to be taught I would say having Scheme and Java is good. As both represent rather formal, but differed approaches. Ruby, on the other hand, feels more lax. I believe that C is now included in the curriculum though(was not yet required when I was there), and so Java has less justification (outside being OO, and Ruby is arguably much more OO than Java).

I think Ruby would be good to teach. I know you mentioned concern that students might get lost in the mix, being as it seems as though nearly everyone involved in Ruby has written a library or two. I don't think they need to concern themselves with that though. I answer 99% of my Ruby questions at the Ruby Class and Library Reference, which lists built-in Ruby classes and modules, and the methods they contain. This doesn't add anything from the standard libraries (where it does start to get deeper). I think that the core functionality is not too hard to pick up and is quite useful.

I also think that the addition of Ruby gives some options that Java didn't seem to. I think it is valuable for programmers to know a scripting language of some sort. It is a somewhat different mindset to get into, and it can be very powerful for aiding you in doing other coding (such as code/documentation generators, automated building/testing). Also, there is certainly plenty of opportunity to teach OO practices, as I understand it everything in Ruby is an object.

I also personally feel that Ruby is much easier to tinker in. The barrier to entry on an individual program level seems lower, so I don't hesitate to write little programs to solve misc problems (such as deciphering a simple substitution cipher for a puzzle a couple weeks ago). I fear this may be the most opinion based argument though. It may be more a reflection of comfort built through heavy use rather than anything inherent to the language. ...

Citing his observation that the languages have different uses, I replied:

That seems right, but in CSC 152 the uses to which we want to put the language aren't perfectly accommodated by either language. Let me run down the main goals of the course:

In response to his observation about the importance of scripting languages, I replied:

This is the main argument I'd give for switching to Ruby. I think of scripting languages as constituting a different problem-solving paradigm, though I'm using a slightly different sense of the word `paradigm' here.

Here are some excerpts from his reply to these last points:

I think the black boxes will remain to some extent wherever you go. I think Ruby could work well here as it seems to not be cumbersome. It tends to guide in more or less the right direction, but leaves a lot of room to do things your own way -- to override default functionality, etc. So I think that exploring these concepts could work well. ...

Rake seems very useful and extensible (though I haven't had need to extend it much), and I have no complaints. I use RadRails as my IDE (a Ruby/Rails adaptation of Eclipse). It's still rather young, and geared mostly toward Rails dev. It's not ideal, but it does what I need. RDE might be a more useful/purer Ruby IDE experience, but I haven't used it personally.

RDoc is useful, and both Ruby and Rails have extensive use of it.

I also find ri (command-line lookup for commands/functions) and rbi (interactive console) quite useful when I'm getting started exploring a new idea or trying to figure out what to expect from objects/functions. ...

I would agree whole-heartedly [that scripting languages constitute a different problem-solving paradigm]. And I think that it is certainly a useful outlook to add to a student's repertoire, though I would also agree that the term `paradigm' both fits and fights usage in this case.

The main argument that other members of the department's faculty have raised against Ruby is that it's not widely used in the mainstream. The concern is that it would be too difficult to persuade students to major in computer science unless we teach, early on, at least one of the languages that is currently dominant in real-world software development.

Update

The preceding post evoked a response from Lindsey Kuper 2004:

Take this with a grain of salt, because I've only recently started messing with Ruby, but I think I want to add my vote to Wes's regarding Ruby in 152.

I've been thinking about it a lot tonight, and I think I understand your point about the potential for language bloat, but if it's the steep learning curve you're concerned about, do you really think that Ruby's will be worse than Java's from the perspective of a student moving from 151 into 152? I mean, I remember the day I saw the Java API for the first time. I was terrified. And then there was the syntax. And the compiling. And, oh, I don't know, the imperative model.

Honestly, I think that those who, like me, did their first real programming in Scheme, in 151, are likely to get a not-in-Kansas-anymore sort of feeling no matter what language they use next, but Ruby doesn't seem like it would be as big of a leap as Java was, because it's interpreted and because of its support for functional programming. Not learning about compilation in 152 means more to cover in 201, I guess -- but maybe it's better that they learn about it in the context of C anyway, while they're learning about the rest of the C toolchain. Hopefully.

Finally, I think it would have done me a lot of good to have learned a scripting language while I was in school. Any scripting language.

I replied:

It depends on what happens to the core language as Ruby matures and stabilizes. I'm much less worried about the libraries, because it's easy to explain to students that libraries are incremental, both in the sense that people add to them over time, and in the sense that one learns them very gradually, as one needs them, and no one knows or needs to know all of them -- that, in fact, there is no such thing as all of them, because new ones are constantly being developed to reflect new needs.

Java's core language, by design, is very little larger than it has to be. It is so tight that, when the designers finally gave in and added inner classes and generics, the new constructions seemed awkward, even though a lot of people really needed them.

Ruby's core language is not that tight, because the designer fancies cute little abbreviations and conventions that supposedly save keystrokes, but make Ruby programs harder to read and the Ruby language harder to learn. One of the destructive effects that the success of Perl has had on the programming-language design community is that it has popularized Larry Wall's boast that there's always more than one way to do it. In my way of thinking, this dictum points to a severe weakness in the design of a programming language. When there's always more than one way to do anything, untalented programmers generally choose kludgy and inefficient ways, and talented ones are constantly distracted by having to think about which of all the different ways is the best.

It's much better when the language provides just one obvious way to do anything (leaving it to the implementer to make sure that the compiler renders that obvious code into the most efficient stream of machine instructions), together with an escape mechanism that talented programmers can use to implement a non-obvious alternative when they can prove that the obvious approach is suboptimal.

Currently, this isn't a really big problem for Ruby, but it worries me that people are still pushing so hard on the core language.