Friday, January 13, 2006

The departure of the hyper-enthusiasts

The departure of the hyper-enthusiasts
by Bruce Eckel
December 18, 2005
Summary
The Java hyper-enthusiasts have left the building, leaving a significant contingent of Java programmers behind, blinking in the bright lights without the constant drumbeat of boosterism.

But the majority of programmers, who have been relatively quiet all this time, always knew that Java is a combination of strengths and weaknesses. These folks are not left with any feelings of surprise, but instead they welcome the silence, because it's easier to think and work.

Where did the hyper-enthusiasts go? To Ruby, apparently. This is chronicled in Bruce Tate's book "Beyond Java," which should probably be titled "Why Ruby is Better than Java." The book is roughly edited; you'll find yourself thinking "haven't I read this paragraph before?" in any number of places, but that's a disappointing experience I've had with several O'Reilly books of late. In many places he plays fast and loose, and almost at the end of the book he declares that he doesn't have time to learn these other languages in any depth -- although he has no trouble condemning the same languages in his rush to Ruby. Such a statement should be in the first paragraph of the book: "I've decided that I love Ruby, so I will condemn other languages without fully understanding them" (in one sentence repeated in a number of places in the book, for example, he declares that C# is no more than a clone of Java). I've been on the rollercoaster of language-love myself in the past and have made similar mistakes; one error in particular was dismissing Python's scoping-by-indentation when I first saw it (months later realizing that we always indicate scoping by indentation anyway, even when we have curly braces available). Now I try to investigate and support my ideas about these things more thoroughly. It takes a lot more time and effort to do so, but it also leaves a more lasting impression.

This is not to say that Tate's book is valueless; on the contrary, it is worth reading. I've learned a number of new and useful things from it. But you must be prepared to be annoyed in places. Tate shrugs this off as being just a matter of opinion, but if you know more than he does about some of the languages he criticizes, you'll realize that, as he admitted, he just didn't want to put in the effort. Because of that, even the new things that you learn from the book you'll wonder about -- did he actually do his homework on this particular topic, or will you be embarrassed in public if you use his explanation? For example, I think I now understand about continuations and continuation servers (which seem to be very powerful concepts), but upon reflection I had better double-check that knowledge elsewhere.

Recently, two people that I know have gotten into an indirect tiff about what "simplicity" means. Martin Fowler (with whom I've organized technical meetings) first made the assertion that the Ruby library was simple and elegant. For awhile, Martin was using Python, but several years ago he departed that camp for Ruby, explaining that Ruby had blocks like Smalltalk and that he liked blocks. He seems to have been happy about his decision.

Martin's argument is that Java's List interface requires you to say aList.get(aList.size -1) to get the last element, and this seemed silly to him. Which it is, if you have unified all sequence containers (that is, list containers) into a single type, as Ruby and Python do. Java, however, follows the C++ STL approach of providing different types based on the efficiency of various operations. The Java libraries do not unify to a single list type because of efficiency issues, so you have to decide if you are going to be fetching the last element from a list a lot, and if you are you use a LinkedList, which does have a getLast() method -- a fact which was completely left out of Martin's original discussion, and the ensuing firefight (other than some ignored comments).

Elliotte Rusty Harold (who took over the management of the Java track at the SD conference from me; I actually lived in the building next to his in Brooklyn for two months once) observed that Ruby's library design didn't seem so simple and clear to him, and he went into detail about many of the methods in the list class, pointing out that they often seemed to make no sense and wondering whether anyone was actually using some of them. Elliotte has spent a lot of time on library design recently, producing the XOM XML library which, I think, represents some very clear thinking. Look at what he writes; I think he makes a good case.

On the other hand, I'll bet that list was one of the first library classes that Matz wrote. You can find plenty of methods and classes in Java 1.0 that appear to be amateurish additions, as well. I think a better test, for both Ruby and Java, is to examine the classes that people have created when they have more experience with the language and its use. I note that I rarely find methods in the Python libraries that make me wonder why they were included, and I think that comes from the maturity of Python (which predates Java). Also, understanding the constraints under which Josh Bloch designed the Java libraries might make you understand that design a little better. Personally, I prefer the simplicity of Python's single list class to Java or C++'s multiple implementations, but a single list implementation must make efficiency compromises. Library design involves compromise, and if such a compromise disagrees with you you're likely to feel it was a bad choice.

Aside from Tate, we know the hyper-enthusiasts have moved to Ruby because of the howls of protest at Harold's opinion (although much of this was before his analysis of list). We can identify hyper-enthusiasts because the arguments have a strongly faith-based flavor to them. X is the true way, therefore anything X is best by definition, and all other languages lack X's goodness. For example, upon discovering metaclass programming, a number of Ruby hyper-enthusiasts (I don't have Tate's book with me, so I don't remember if he was one), have declared that Python is incapable of metaclass programming, which is untrue. It may be true that Ruby's metaclasses are easier to grasp and use than Python's, but Python has had the capability for many years.

Ruby is to Perl what C++ was to C. Ruby improves and simplifies the Perl language (the name "Ruby" is even a tribute to Perl), and adds workable OO features (If you've ever tried to use classes or references in Perl, you know what I'm talking about. I have no idea whether Perl 6 will rectify this or not, but I stopped paying attention long ago). But it also seems to carry forward some of the Perl warts. For anyone used to, and tired of, Perl, this certainly seems like a huge improvement, but I'm tired of all impositions by a language upon my thinking process, and so arbitrary naming conventions, reversed syntax and begin-end statments all seem like impediments to me.

But it's hard to argue that Ruby hasn't moved things forward, just like C++ and Java have. It has clearly shaken the Python community up a little; for a long time they were on the high ground of pure, clean language design. Although the Perlish warts in Ruby don't have that cleanliness, when Matz started from scratch on Ruby he was able to look at the problem in a fresh way and he's done some things that have made the Python core folks look again at "what problem are we solving?" Ruby, for example has coroutines, as I learned from Tate's book. The expression of coroutines in Ruby (at least, according to Tate's example) is awkward, but they are there, and I suspect that this may be why coroutines -- albeit in a much more elegant form -- are appearing in Python 2.5. Python's coroutines also allow straightforward continuations, and so we may see continuation servers implemented using Python 2.5.

And of course, who can ignore Rails? The backlash from heavyweight web frameworks has been significant. We now know that EJB 1 & 2 were based on an entirely flawed set of use cases. Because of the damage this (still slowly dawning) realization has wrought to Sun's reputation, it's hard to know whether EJB3, which probably should have been called something else to disassociate it with the failures of its predecessors, will succeed, despite the fact that EJB3 is like a breath of fresh air. You look at the code and it makes sense; no bizzarre and obscure interfaces and concepts to puzzle over while thinking, "I wonder why I have to do this? Well, these guys are clearly smarter than I am." (I tried to understand EJB1, but when I first heard that entity beans didn't actually work, my brain refused to let me invest any more time, which turned out to be the right choice). As a result of all this, someone said "hey, all I want to do is create a database and use it from the web. Why should I do all that work?" As it turns out, such activities seem to be about 90% of all we ever do in "Enterprise" programming, and EJB 1/2 were solving an entirely different problem, and making the 90% incredibly difficult in the process. Thus, the Rails approach of "just connect the database to the web."

Rails brings up a deeper issue, as well. Apparently, something "relatively simple that you only do once," such as setting up the database by writing SQL, really does benefit from automation, possibly because you actually end up doing these things more than once. Or possibly because simplicity of both expression and of understanding really is important. There is a faction among us that seems to feel that if you can do anything at all, it doesn't matter how many hoops you must jump through to accomplish that thing. These are the folks that assert that Java's verbosity is "just finger typing that Eclipse/IntelliJ will do for me," and it doesn't matter if the resulting code has 20 times the visual bulk of a simpler approach. One of the basic tenets of the Python language has been that code should be simple and clear to express and to read, and Ruby has followed this idea, although not as far as Python has because of the inherited Perlisms. But for someone who has invested Herculean effort to use EJBs just to baby-sit a database, Rails must seem like the essence of simplicity. The understandable reaction for such a person is that everything they did in Java was a waste of time, and that Ruby is the one true path.

The Rails fallout in the Python community has been significant. Pythonistas have been busy since the beginning of the web, trying to understand the problem and spinning off a multitude of web frameworks to solve it. Because of the confusion in the web space in general (hindered further by the dead-end reasoning behind EJB1/2 -- how many billions of dollars were wasted by this?), there was no nucleating agent that made any one of these frameworks come forward as clear winners, although it might be argued that Django had been in development for several years and appears to predate Rails, even if it wasn't public until after Rails.

My own experience in web frameworks was with Zope. In an interesting parallel with EJB3, Zope is now on version 3 which is a from-the-ground-up redesign, and everything I've seen of it indicates that, like EJB3, it represents a great deal of rethinking of the problem. I've been bumping up against the problem of "but all I want to do is connect a database to the web" in Zope2 for several years now. Oh, it's definitely something you can do, but unfortunately it's past the knee of the "Z-shaped learning curve," and is only trivial if you live and breathe Zope every day. Don't get me wrong; Zope is an excellent system and incredibly powerful, and Zope3 may be much easier, but I'm out of steam. I have realized that on my site, I really just want to do a collection of simple things, and I don't want to relearn Zope every time I want to accomplish something. So -- sorry, Jim (Fulton, not Kirk) -- I'm going to find something drop-dead simple to solve my drop-dead simple problems. Probably PHP5, which actually includes most of Java and C++ syntax, amazingly enough, and I wonder if that isn't what made IBM adopt it.

I'm sure we will find that the Rails approach isn't the ultimate solution; there will be plenty of other problems that we need to solve on the way to making web development easy. But it represents a fundamental restart in the thinking process. And it has caused, in the Python community, attention to Django, the development of Subway (although I don't know how that one is faring), and the creation of Turbogears, which seems like a very good solution because it builds on best-of-breed existing pieces using a Rails-inspired approach.

Clearly Ruby is making important contributions to the programming world. I think we're seeing the effects sooner in Python than elsewhere, but I suspect it will have an effect on Java as well, eventually, if only in the web-framework aspects. Java-on-rails might actually tempt me into creating a web app using Java again.

However, I can't see Ruby, or anything other than C#, impacting the direction of the Java language, because of the way things have always happened in the Java world. And I think the direction that C# 3.0 may be too forward-thinking for Java to catch up to.

But here's something interesting. I was on the C++ standards committee from the initial meeting and for about 8 years. When Java burst on the scene with its onslaught of Sun marketing, a number of people on the standards committee told me they were moving over to Java, and stopped coming to meetings. And although some users of Python like Martin Fowler (who, it could be argued, was actually a Smalltalk programmer looking for a substitute, because the Smalltalk relationship never really worked out in the real world) have moved to Ruby, I have not heard of any of the rather significant core of Python language and library developers saying "hey, this Ruby thing really solves a lot of problems we've been having in Python, I'm going over there." Instead, they write PEPs (Python Enhancement Proposals) and morph the language to incorporate the good features.

I think we've mostly been hearing from people who have come from Perl and found Ruby to be a "better Perl, with objects that work," or people who are finally convinced that dynamic languages have merit, and so mix the enthusiasm of the first time dynamic language user (quite a rush, as I remember from my 2-month experience with Perl many years ago) with their experience of Ruby. So far, I've heard from the hyper-enthusiasts about Ruby being cool, or that it has begin-end blocks and they don't like indentation to delineate scope. That kind of thing: "I like this, I don't like that," which is fine but not compelling. The person I want to hear from is the core Python expert, someone who knows that language incredibly well, who has decided that Ruby is just so much better that all the mature Python libraries and community expertise doesn't hold a candle to the value of moving to Ruby. That person would be able to make a compelling, feature-by-feature argument (such an essay is better served as his or her own weblog entry, rather than posting it as a comment here).

About Bruce Eckel

Bruce Eckel (www.BruceEckel.com) is the author of Thinking in Java (Prentice-Hall, 1998, 2nd Edition, 2000, 3rd Edition, 2003, 4th Edition, 2005), the Hands-On Java Seminar CD ROM (available on the Web site), Thinking in C++ (PH 1995; 2nd edition 2000, Volume 2 with Chuck Allison, 2003), C++ Inside & Out (Osborne/McGraw-Hill 1993), among others. He's given hundreds of presentations throughout the world, published over 150 articles in numerous magazines, was a founding member of the ANSI/ISO C++ committee and speaks regularly at conferences. He provides public and private seminars & design consulting in C++ and Java.

No comments: