In my previous post I explained why I left JavaEE behind. Now, I’m going to explain my reasoning process to come up with what I’ll learn, teach and use next. The criteria I’m using are:
- Cloud friendly: the technology should be ready to scale horizontally, without constraints, additional products or exponential use of resources.
- Learning curve: I should be able to learn and teach fast even if it requires me to change the way I think about programming. I recognize I have lots of new concepts to learn before I realise the advantages of other technologies.
- Performance: everything I write I want to be faster than any interpreted language. I know that premature optimization is a bad idea, but I need a technology that even when I decide to postpone optimizations it will be fast enough.
- Community: the community doesn’t need to be big, but it should be active and kind with newcomers. The majority of libraries they produce should be open source.
- Reusability: I should be able to reuse the libraries I’m used to, or find equivalent ones.
- Coverage: I should be able to write the same kind of software I’m used to and not be limited if I decide to do more.
- Documentation: the technology should be well documented, with books, websites, blogs, wikis and teaching materials.
- Development Stack: the stack should implement MVC for web applications, database migration, database abstraction, SSL, authentication, authorization, REST web services, etc.
The fundamental choice starts with the programming language. It must support functional programming in order to be cloud friendly, but it also has to avoid mutable state to prevent concurrency issues and make it difficult for programmers to write code with side effects. I already use Java, but at this point we have to eliminate it because mutable state is the default behaviour in the language. To avoid it, we have to write a whole bunch of additional code that needs to be tested as everything else. Java requires the use of design patterns to overcome the deficiencies of the language. Static analysis tools, such as SonarQube, are required to keep the code safe, but, unfortunately, they require a significant effort that has nothing to do with the business problem we are solving.
“Most people talk about Java the language, and this may sound odd coming from me, but I could hardly care less. At the core of the Java ecosystem is the JVM.” James Gosling (2011, TheServerSide)
Despite the Java programming language being out of the picture, the Java Virtual Machine (JVM) is still relevant. It’s a portable and mature platform capable of running multiple programming languages in several operating systems with a transparent memory and thread management, with performance peaks compared to C/C++. What Java doesn’t do for us, other programming languages do, running in the same virtual machine and reusing the existing Java ecosystem, which is huge! Therefore, languages that have their own compilers and independent virtual machines are discarded because they hardly will reach the maturity and popularity of the JVM and the Common Language Runtime (CLR). So, at this point we discard Erlang, Harskell, Go, and all other languages that don’t run in the JVM or CLR.
I have mentioned CLR, the .net runtime, but I have no experience with it so far. So, I have to narrow my choices to JVM hosted languages. I couldn’t find any official or reliable survey about the popularity of JVM languages, but I did find several pools showing that Groovy, Scala, Clojure and JRuby are indeed the top four JVM hosted languages, in no specific order.
Groovy‘s popularity is due to the fact that it looks very much like Java, but without its cumulative historical problems. Therefore, Groovy’s learning curve for Java developers is by far the lowest one compared to Scala and Clojure. Scala comes next with its richer type system and object orientation. We’re able to map our Java knowledge within Scala, but this language is so full of possibilities that it’s the hardest one to master. We have problems to read other people’s code because developers have too much freedom to express themselves. Clojure, on the other hand, is the hardest one to start programming because of its radical differences from Java, but it’s the easiest one to master because of its simplicity. We do a lot more with less code and the code is readable as long as you know functional programming principles. Since JRuby didn’t perform well in the surveys above, I’m discarding it for the moment.
The chart bellow shows job trends in the US, according to indeed.com. It actually reflects the size and influence of the community gravitating those languages. Groovy has been performing well since the beginning, but it is now threatened by Scala, although it isn’t clear yet which one will stand out. The interest for Clojure is constantly and shyly increasing, as functional programming becomes popular and the learning material available helps to reduce the introductory learning curve. In any case, it still has a long way to go.
Groovy, Scala and Clojure have at least the same coverage as Java, with the advantage of writing less to do more. There is absolutely no problem that can be solved only by using Java. Actually, concurrency problems are far more complex to solve with Java, making those alternatives much more interesting.
In order to master those programming languages, I had a look at the volume and quality of the documentation available. This is very hard to measure. For those who like numbers, I have compiled the following table:
The problem is that this table can be interpreted in many different ways:
- These numbers are far from precise. They change everyday because of the nature of the internet.
- Looking at the volume, we might conclude that the more entries we get the more documentation we can find, but it can also be a sign of complexity, taking a lot more documentation to explain a thing. Therefore, the fact that Clojure has less entries doesn’t mean it is less documented than Scala or Groove.
- Some languages are older than others, accumulating exposure to the community, thus producing more content. But in this case, older content are counted but hardly relevant nowadays.
I can say that the documentation I found was fairly good enough to address all my questions so far.
The last point is the development stack, a set of libraries and frameworks covering most of the needs of a regular enterprise developer. The following table shows a non-exhaustive list:
|Compojure + Ring
|RESTful Web Services
Notice that Grails appears several times in the Groovy column. It’s a web framework offering a good deal of productivity thanks to a Convention-over-Configuration approach. The same happens in the Scala column with several occurrences of Play Framework. While the approach followed by Groovy and Scala offers more productivity and reproducibility, it also reduces the flexibility of the architecture, making it hard to replace an inefficient part by a more efficient one. Clojure is more concerned about the architecture and offers a separate library for every feature. In case a competitor library becomes more efficient than the one we are using, we can easily integrate the new library and gradually replace the inefficient one.
My strategy to use those three technologies from now on is the following:
- Groovy: when I find a chaotic and inefficient JavaEE application, I will propose to migrate it to Groovy + Grails. It will make the project economically viable again and recover the time wasted with complexity. The team can start writing Groovy code right away in the same project, gradually replacing the Java code and JavaEE dependencies.
- Scala: the main advantage of the Scala stack is its reactive platform, offering an unprecedented performance boost for concurrent applications. So, when performance is one of the main requirements of the application and the team is smart and organized, I will suggest Scala as the way to go.
- Clojure: For everything else I will suggest Clojure, which is very productive, simple and has an excellent performance. That’s by far the best programming experience I ever had.
In summary, I still use JavaEE for existing well designed applications, but I will use Groovy to save chaotic JavaEE applications from complete failure. Scala and Clojure will be used for new projects, depending on their characteristics and context of use.