My kid brother, Private Jesse D. Fronk, recently joined the US Marine Corp and completed combat training. This is where a bunch of 18 year old kids spend six weeks shredding moving and stationary targets using various projectile, mounted, and hand propelled weaponry including grenades, grenade launchers, hand guns, rifles, and machine guns. He talked a lot about the SAW (big/sometimes-mounted machine gun) and the grenade launcher but when I asked which weapon he would prefer if he were to find himself in a hostile situation where he was unsure of what kind of crap to expect, he replied, "The M16 rifle - hands down."
I thought this was a bit odd after he had just went on about the pure bliss in blowing things up with the grenade launcher but the reason is simple really: the M16 is the most efficient and productive general purpose tool for producing casualties (or so believes the US military) on the planet. It is light, quick, powerful, reliable, and cheap. However, it is not the only weapon and it would be absurd to suggest that a single weapon could outperform the specialized ones at specific tasks.
Coding is a lot like killing people, insofar as choosing the tool is a bit of a science in itself. In terms of productivity, reliability, maintainability, and performance, the language you choose will likely have more impact than any other decision you make, so it is important that every developer have a good understanding of what languages are available to them and their relative merits. Most coders have a language that plays the same role as the M16 plays for my brother. Unfortunately, most also have strong religious attachments to this One True Language and this is bad because religious attachments to things like programming languages usually results in a lack of objectivity. It's important that we place ourselves in a position where we are able to constantly weigh our languages and practices against what else is out there.
When Java came on the scene, the industry adopted it very quickly, religious attachments aside. The language and standard library was a huge improvement on what most had been exposed to at the time. The fact that so many saw Java as a better general-purpose language and moved quickly to adopt it is not surprising in the least - it's exactly what you would expect to happen. Something better came along and you were faced with the choice of either jumping all over it or becoming irrelevant.
The benefits of Java came with some downside though, and there was a lot of nay-saying going on. You couldn't build drivers that talked to hardware with Java like you could in C, you couldn't build Windows apps as quickly as you could with VB, you didn't have high performance templating features like C++, you didn't have the God given liberty of performing pointer arithmetic, etc. But for the most common tasks, let's say 80%-90% of the code that needed written, Java hit the sweet spot and so became the M16 of enterprise development. Of course, Microsoft followed that up with .NET and gave Java some good competition in the statically-typed/interpreted space. So much so that recent numbers seem to be showing something close to a 50/50 split in the market. But even with all the adoption of byte-code languages you still had 10%-20% of code that still needed a lower level language like C.
The adoption rate of Java and .NET provides a pretty good baseline for what you should expect from a sweet spot language in a functioning technical community. i.e. When something comes along that does 80% of what you're doing today better than what you're using today, you need to switch. But something strange has happened over the past couple of years that, I believe, has shown that sweet spot languages aren't guaranteed to overthrow their predecessors just because they can do 80% of their chores better. If 80/20 was an absolute law, dynamic languages like Python, Ruby, and most recently Groovy would be eating away a far greater number of lines of Java and .NET code right now.
The case for dynamic languages is, in my opinion, not something we can look down on from our static-typing ivory towers and laugh at. The amount of code required to perform almost any task in Java can be reduced three-fold in any of the dynamic languages I mentioned. Combine this with the fact that unit testing has reached massive adoption and you end up with an interesting situation: using a dynamic language means that you can write the main code and the unit tests with less code than it takes to write just the main code in a statically typed language. Now combine this again with the fact that the dynamic languages I mentioned are, contrary to popular belief, strongly typed, and that with unit tests to cover the code, you get most of the type checking benefits of a strong/statically typed language plus the added benefits of unit tests and I think it's hard to argue that we're not looking at a new M16.
This isn't to say that we get rid of statically typed languages altogether - they are still extremely relevant and I believe static and dynamic languages should be used together. In fact, this is where most arguments for dynamic languages make a huge mistake in my opinion. I've been convinced that trading off compile-time type checking for less code, more tests, and greater flexibility is always the right decision. Always! But I am not convinced you can make the same tradeoff for some of the other benefits of statically typed languages.
Static typing is useful for more than just compile-time type checking and you lose a lot of these values when you move to a dynamic language. One benefit that should immediately come to mind is performance. Static typing will always provide speed improvements over dynamic typing. Here's another one that I think is overlooked and that I've only come to really value after working with Python for awhile: static typing is documentation. In fact, I'm going to say that this is the primary benefit of static typing. I really like being able to go look at a method signature and determine exactly what needs to be passed. Not only that but the tools are able to use this information as well to do all kinds of nifty stuff like provide code-completion, generate API documentation (Javadoc), or even automatically spit out WSDL to turn a Java interface into a SOAP based service. These are things you just cannot do reliably in a dynamic language like Python and it's one of the very few things I miss from Java.
I think we need to start looking at the things we build a little more closely. OOP taught us to think about everything as a set of objects aligned on a single plane but I'm finding that the really strong OOP characteristics start fading as you move up out of reusable-component land and into real application land. It seems like we should be able to draw a line between reusable object components/libraries and the glue code that puts the reusable objects together to make them do something useful.
Static and dynamic languages seem to fit these two planes nicely. Reusable object models generally provide lower level functionality. It's important for these to have well defined interfaces, strong documentation, and this is also usually the most effective place to be thinking about optimization. I think using static languages at this level makes a lot of sense. Now move up into the messy glue code area where a real application starts to take shape. Things like optimization become less of an issue, and code in this plane is rarely reused. Further, it's important that we're able to try a lot of different variations with frequent refactoring. Dynamic languages make this type of work much easier.
And now a prediction: the first environment to successful mesh static and dynamic languages into a coherent platform will win the interpreted byte-code market. Right now I see two-and-a-half contenders.
Sun has the best situation but they are stupid. Groovy and Java are a
perfect match. But unless Sun takes Groovy into the core and makes it an
official sibling of Java, it's just not going to have the uptake it needs
to be successful. Groovy has to be everywhere
javac is. The only thing I
can speculate here is that Sun went through so much trouble to ensure that
Microsoft didn't hijack Java that they are now having a hard time
justifying a variation like Groovy. Or it may be because Gosling is holding
onto the belief that Java is just C++ for incompetent ass-hats. Another
language would just send the average Java developer into a coma. Sad.
- Stop what your doing.
- Call Bob.
- Pay him and his minions whatever they want.
- Push your little JSR through for Groovy.
Microsoft is in a worse situation but they are smart (and evil). Case and point (and tragically hysterical too). First, Jim Hugunin writes an entire implementation of Python in Java that runs on a JVM and can even compile Python down to Java byte-code. He does this in his spare time, to make a point, I suppose. Next, Sun doesn't notice. Seven years later, Jim releases IronPython, an entire implementation of Python in .NET that runs on the .NET framework and can even compile Python down to .NET CLR byte-code. The next day, Microsoft hires Jim on as a core CLR hacker to improve support for dynamic languages on the CLR.
And last but not least, the dark horse in all of this: The Mono Project. Here's why I think these guys might be in the best position of all: first, they aren't stupid. Second, they aren't evil. Last, they don't have 50 other languages complicating things. I have a feeling that Python might get lost next to the other languages supported with .NET. In my opinion, you need to take the best static language and the best dynamic language, mash them together and get rid of the rest of the cruft. Mono is in exactly this position with C# and Python. But they have other issues, not the least of which is that they have a hard sell in trying to convince the GNOME hackers to adopt technology spewed forth from Redmond. It's hard to blame them with Microsoft's recent patent activity.
I have a feeling I'll be sticking with good ol' CPython backed by good ol' C code for the next year or so but this will be fun to watch... maybe.