As a Java developer for the past 13 years, I’ve always attempted to learn about other languages. I find programming languages similar to natural languages in that once you understand the ground rules, learning new ones becomes much easier. For example, once you understand iteration, you can expect every language to have a variant and you go look for it.
The “Holy Grail” of computer languages is productivity. Fingers writing code is an expensive resource; therefore, we must look for the right tools to optimize those resources. While you can solve nearly any problem in literally any language, most are best-suited for certain comfort zones. For example, you typically wouldn’t use Ruby to write device drivers and you wouldn’t use C for a CRUD Web application.
When you take into account productivity, maintainability, testability, and adaptability, it can become quite a chore in choosing the right language for the job. Many enterprises will choose a language based upon a one-size-fits-all approach to development, while others will try to exploit more nimble tools like Ruby and Rails to solve problems.
What I’ve found from years of looking at projects (large and small) and talking with people, is that the biggest driver in selecting a programming language for a project is complexity.
I’ll use Java as a baseline since it is a well-known quantity with an extremely mature ecosystem:
Java tends to take a hit on initial ramp-up due to the excessive amount of options available and the configuration. However, once you get it going, it is pretty consistent.
In the graph above, complexity can mean many things; therefore, I intentionally left the scale blank on the x-axis. Factors that impact complexity can include the size of the codebase, number of developers, difficulty of the problem, duration of the project, quality of the code, overall design, and even the number of modifications. Progression along the complexity axis isn’t a given, it is a variable that can be managed.
The speed at which a project traverses across the graph is not constant. For example, a large waterfall project with 30 developers on a multi-year project could move into the red zone almost immediately. Whereas, a small project sticking closely to a high-level framework may never cross into the red zone.
There have been attempts to improve the productivity of a straight Java application. Spring Roo is one of those attempts. It tries to boost that initial productivity before Java hits the flat line.
While this can provide a nice kick start to a project, it still doesn’t address the long-term productivity of a typical Java project.
One way developers have sought to boost productivity is through dynamic languages. Ruby, in particular, has earned a lot of fans for its expressiveness and simplicity. The Rails framework made Web development simpler by providing an out-of-the-box set of best practices and convention over configuration. It provides a huge boost in getting a project off the ground.
The challenge with Ruby, and most dynamic languages, is what happens when the complexity demon rears its head (see graph below).
Given enough complexity, a dynamic language can eventually reach that tipping point where the very nature of the language makes it more difficult to work with than straight Java. You’re now in the red zone of reduced relative productivity. This would typically manifest itself by features taking longer to complete than expected or requiring significant rework to implement.
With dynamic languages, this can also manifest itself by getting bogged down in writing more unit tests to cover edge cases that compilation via a static language would catch for free. Most of the causes can be attributed to excessive technical debt.
None of these design or code issues are unique to Ruby. When they occur, they have a more negative impact on productivity compared to Java.
The interesting developments in languages today are attempts to bridge the gap between the well-known linear productivity of Java over time and the cost-effectiveness of highly productive languages at less-complex problems. One of the most interesting ones is Scala and the Play Framework. By combining the power of Java with improved expressiveness and functional language features, it remains a statically typed language. If it lives up to its promises, I suspect it will be a solid, incremental improvement over straight Java.
Anyone assuming that dynamic languages aren’t viable and that you should always use Java is missing the key point about complexity. As the talented folks at 37 Signals have demonstrated, it is completely possible to write large, enterprise-scale products using Ruby on Rails. I would wager that they achieve that success by carefully managing where they are on the complexity continuum.
A small, highly-skilled team with extreme attention to detail can achieve enormous productivity boosts by using a dynamic language. Technical debt is the mortal enemy of these teams. By staying in the green zone, these teams can do incredible things faster than would be possible in Java.
On the other end of the scale, you have the typical Fortune 500 “large” projects, which tend to be driven by cumbersome waterfall processes, and little attention to technical details and long-term design of solutions. These kinds of projects are better served by languages like Java, since they are almost guaranteed to end up deep in the red zone. Scala is a possibility for these teams, but it is still an emerging skillset and large IT shops don’t like to paint themselves into difficult-to-staff technologies.
At Credera, we have significant experience helping clients of all sizes make solid technology decisions. If you have questions about this blog or a technology decision you are facing, please contact us at 972.759.1836. We’re here to help.