The Patriots loss in the Superbowl has gotten me so depressed and down that I need to take it out on somebody. I need to rant about something, so why not about some things that have annoyed me over the past few months about the dynmaic language community.

I recently emailed the mandelbrot benchmark to a dynamic language evangelist colleague. Although benchmark results are usually pure propaganda, poor representations of how a language or framework is used in the real world, or even just plainly out of date with the latest versions of the technology, still, the performance of dynamic languages compared to Java in the example is quite embarrassing. Ruby, for example, is 500 times slower! Yeah, its hard to take seriously a benchmark that outputs to stdout, but still, if you look at the code you’re thinking, WTF is Ruby doing that causes so much overhead?

Now, when I forwarded this benchmark to my evangelist colleague, he immediately accused me of trying to put down or stamp out any challenge to the “One True Language” (Java). Its not about putting down or stamping out. Its about testing whether or not a language is a viable application platform. The thing is, if the dynamic language crowd is going to position itself as a replacement for Java in application development then they are going to have stop giving silly rationalizations for their shortcomings and promoting myths about their language and Java. This, and this alone is what irritates me about this crowd. Let me give you some examples about the rationalizations and myths they try to pull over on us:

RATIONALIZATIONS

Dynamic Language XXXX didn’t do well against Java in XXXX benchmark

Rationalization: “Benchmarks indicate very little practical information about the overall utility and performance of a given language or runtime.”

Reality: Although benchmarks are either propaganda, out-dated, or not a good representation of real-world usages, glaring differences must be recognized. A 5%, 10%, or even 100-200% difference is probably as a result of tuning or some simple undiscovered bug. In the grand scheme of things, those kind of numbers ain’t very relevant. But a 50000% difference? For such a simple benchmark? Something is seriously wrong here.

This reminds of 2002, when I first ran JBoss against the J2EE SpecJ benchmark. We had some pretty embarrassing numbers at first way back then. Although SpecJ is clearly a silly, non-real-world benchmark, it allowed us to identify many major and minor bottlenecks and helped our project to mature. For some dynamic languages like Ruby, I think what the mandelbrot benchmark showed was that the VMs/implementations of dynamic languages like Ruby are still very immature compared to Java. I don’t believe that it shows anything seriously wrong with the language syntax of these dynamic languages themselves though. Java received similar attacks in the mid 90s when it came out. Since then, the JVM has improved dramatically and according to the mandelbrot benchmark, only 10% slower than C. I expect the same out of the Ruby guys eventually. I’ll have to see how this benchmark improves under JRuby.

Ruby VM cannot support kernel threads

Rationalization: “Green threads are good enough.” OR: “Who cares, I can just run multiple processes.”

Reality: Even the basic laptop nowadays has parallel computing power. Green threads don’t take advantage of this. Blocking I/O also creates huge problems with Green Threads. Solving the problem by running many processes is a poor solution. A process is just too heavy weight compared to a thread which is why we have threads in the first place. It is very common for server-side Java applications to service hundreds of concurrent users. Besides, running multiple single-threaded processes starts to negate some of the benefits of simple design patterns like caching.

If dynamic languages like Ruby want to position themselves as a viable alternative to Java for an application platform, they are going to have to solve these issues. Many will say, “Its probably good enough for simple apps”, but it is not uncommon for project leaders to underestimate how much traffic they will get, or how much they have to scale.

Dynamic languages like Ruby, Python, etc… are not typesafe/statically typed

Rationalization: “Type-safety makes my code too verbose and makes me less productive.”

Reality: Why can’t these people learn how to type? Modern IDEs make this point totally moot with code completion and code generation. Besides, why can’t we have a dynamic statically typed language?

Lack of type safety doesn’t scale well to large teams

Rationalization: Anybody noticing the “Any software written by a large team will ultimately fail.” articles floating around in the community? Am I paranoid, or is this yet another attempt at brainwashing us into believing dynamic languages are the next fad in software development?

Reality: There are a lot of large applications in the industry being written. This reminds me of a story my colleague Jason Greene told me. He was working on a very large python project. Lack of static typing ending up being such a coordination and maintenance problem they ended up having a coding policy where everybody had to embed type information into the variable names of method parameters. Funny, eh?

Lack of static typing does not allow for reliable refactoring in modern IDEs

Rationalization: “The productivity of dynamic language XXXX makes refactoring irrelevant. Anyways, there are IDEs for Ruby out there that support refactoring”. OR, my favorite: “I don’t use an IDE, what do I care?”

Reality: I was a VI/Emacs user up until 2002 when Intellij came out with refactoring capabilities. Up until then, I was as productive with emacs, find, grep, and sed as I could be with any IDE out there. After finally becoming familiar with Intellij and its refactoring capabilities, I found that I was 5, 10 times more productive with my IDE than I was before. Now, Ruby fanboys will argue, “Intellij and Netbeans have refactoring capabilities for Ruby!” My answer is, it is not reliable refactoring. Take this example Cedric Beust gave on a recent TSS thread:

def f1(o)
  o.init
end   

def f2(o)
  o.init
end   

class C
  def init
    ...
  end
end    

class D
   def init
     ...
   end
end

If you rename C.init to C.init2, how can the IDE know which o.init must be renamed in f1 and f2? The IDE could either do these refactorings automatically (dangerous) or prompt you to confirm at each replacement point (tedious). In either case, any productivity you’ve gained with the elegance of Ruby is lost 10 times over.

So, these are just some of the rationalizations the dynamic language crowd gives when confronted with criticism. Now let’s talk about some of the myths and propaganda that is being fostered.

MYTHS

Software Engineers should use the best language for the job

Reality: I don’t know about the rest of you, but throughout my career I’ve either been developing middleware or writing applications. What other job is there really out there? Or maybe they are saying, “XXX dynamic language is good enough to solve certain application requirements”? Good enough has never really been good enough for me.

Besides, its hard enough to find an expert in one language. Its a maintenance and integration nightmare to have a project written in multiple languages. This can be bridged, to a degree, with dynamic language implementations that run on the JVM: JRuby and Jython are good examples. But unless these implementations become mainstream, they can quickly become out of date, i.e. Jython.

More lines of code means more bugs, thus dynamic languages are better.

Reality: Modern IDEs fills this gap. TDD is viable in type-safe languages too! I’m probably doing my own rationalization here, yes… JBoss 5, for example, is the 3rd major refactoring of the JBoss Application Server that I’ve lived through. I just can’t imagine doing it without the reliable refactoring that modern Java IDEs provide.

I am more productive in XXX dynamic language because the syntax is cleaner, more elegant, and more powerful.

Reality: Because Modern IDEs with a statically typed language can do reliable refactoring, this productivity gain has diminishing returns as your project gets larger. Even with small, one man projects, this reliable refactoring offsets any productivity gain you get with the dynamic language. At least, that’s what I’ve experienced.

I’ve done a decent sized project in Python before. I did find I was more productive with the first implementation. The problem is, I’m not a very clean programmer, so I end up iterating and refactoring constantly. In my case, a powerful IDE has made me incredibly more productive. Something I just could not get with a dynamic language.

Am I just a Java fanboy?

Maybe, but I don’t think so. Throughout my career I’ve done projects in Pascal, assembly, C, C++, Fortran, Tcl, Perl, Python, Visual Basic, Java, and even hacked around a little bit with PHP. While I don’t believe that Java is the one langauge to RULE THEM ALL, I do believe it is vastly superior to anything out there to build applications with. I also do not believe that Java is the end all, be all of existence. It still needs elegant, typesafe closures to complement annotations as a way to implement DSL. It needs a standard, non-code generating way of adding behavior to annotations. It needs a structural syntax to make initialization easier. AOP support might be nice too, or at least JVM support to make it easier to implement AOP-like features. Better zero-turnaround development features in both the JVM and APIs like Java EE, Seam, Hibernate, Spring, and JBoss AS would help out tremendously as well. Really, I’d be fine to dump Java for a language that supports all these things but the new language must:

  • Be typesafe, statically typed
  • Have an IDE that supports the same features as modern Java IDEs
  • Have a rich set apis and libraries to build my applications from
  • Have a viable commercial ecosystem
  • Have a vibrant open source community

While current dynamic languages do have some of these attributes, none contain all, so until then Java is my choice and I will remain a boy who is a Java fan.

Finally, I hope you realize that I’m not trying to stamp out dynamic languages, but rather hoping, in vain, that the dynamic language community admits their faults. I do wish that a statically typed dynamic language would come of age, but until then, I’ll stick with Java. Really, I don’t know why somebody hasn’t done it it. Is static typing really that hard to implement well? For example, why not gut Groovy and have Dynamic Java? Or do the same with Scala? Or add static typing to Python and get Jython up-to-date?

Well thats it, expect more ranting in the next few weeks/months on a variety of subjects. Its gonna take a long long time to get the Pats loss out of my system….

Edited: 2/22/08

Many people have been confused on what I meant by statically typed dynamic language.

1) Typesafe introductions/mixins to either an instance or a class

For example:

class Foo {}
class Mixin implements MixinInterface {}
Mixin.add(Foo.class, new Mixin(), MixinInterface.class);
Foo foo = new Foo();
 MixinInterface intf = (MixinInterface)foo;

Or:

Foo foo = new Foo();
Foo bar = new Foo();
Mixin.add(foo, new Mixin(), MixinInterface.class);
(foo instanceof MixinInterface) == true
(bar instanceof MixinInterface) == false

2) Ability to do AOP things like field/method/constructor interception without having to do bytecode magic
3) Ability to plug in at runtime annotation processing (not the Javac crap).
4) An instrument library that allows you to make schema changes to classes. (didn’t state this before)