I have recently had a minor enlightenment about what programming languages I want to use in my daily work, and I would like to capture them for the benefit of new and experienced programmers in search for an addition to their toolkit.
I want to preface this by saying that of course there are niches (small and large) and "killer libraries" for those niches that may render all of my arguments moot; I'm talking mostly in the context of doing "general-purpose" services and applications that run on a few servers somewhere. Certainly web services, but also other not-so-web services.
Consider Python in the context of web development. It has a few very mature web frameworks out there, a fantastic asynchronous networking library, an excellent and vibrant community — yet always there is a "ceiling" of load that a web application can handle before getting rewritten to something else, usually Go, perhaps Java; certainly a less dynamic and closer to the metal language that has "real concurrency".
Even by replacing the CPython VM with something like PyPy, you still have to the GIL and therefore you have to have some event-loop based mechanism to do concurrency (sadly other VMs like Jython and IronPython didn't survive the Python 3 transition, so we'll never know what a multi-core Python could work like in practice).
I don't mean to single out Python; Ruby and NodeJS also suffer from this ceiling; The moment you want your web service to do something more "interesting", you start to pull in the dependencies: Redis, RabbitMQ, Memcached and a host of similar tools that are capable of running for a long time, serve multiple concurrent connections in one process, maintain state and not leak memory.
Even by taking those out of the counting, there's certainly no shortage of languages to consider. You can easily spend a week going over the TIOBE's 100-most-popular languages index, trying to compare strengths and weaknesses for each.
Assuming though that you need something cross-platform and general-purpose enough, here's my thinking:
- Pick the ones with a runtime (or VM);
- Evaluate the runtime (or VM) instead;
- Pick a language that targets the runtime that suits you.
Why runtimes are important:
A runtime usually only gains in performance, security, stability and you get all that for free, without having to rewrite your code.
Using a multi-language runtime means you benefit from existing libraries in other languages, assuming a sane interop strategy.
New languages will appear that target your runtime, and you can choose to write parts of your system that make sense in them, without ditching your entire codebase.
I think this whole exercise narrows it down to only a handful of contenders:
My second a-ha moment: You want to focus on the runtime and not the language, because the runtime is what makes or breaks your software in production. The obvious point here is where are the languages that target the Go runtime? Does a Go runtime even exist?
All three are old and battle-tested enough across a whole range of companies and services that should be safe bets. Also all three have major corporations (Oracle, Microsoft, Ericsson) funding their maintenance and development. You really can't go wrong by picking one of those three. Perhaps you'll rule out CLR since it only recently (partly) became Open Source.
From those three, BEAM is quite interesting; It's the only VM I know of that provides pre-emptive concurrency, so that you don't have to write "cooperative" code. Of course, that comes at the tradeoff of performance and expressiveness (in the sense that you can never have shared memory, if you need it). But still you can go quite far.
Elixir has quickly gathered a community of developers that are giving back a lot of useful libraries; plus, as mentioned before, you get access to all the existing and battle-tested Erlang libraries. I personally think that if you're developing web-services without crazy number-crunching requirements, you should really look into Elixir and OTP.
If you want something more general purpose, you might want to look into Clojure; my tip for sticking with it is to keep counting the parentheses: it's always the same number as with your current language, it's just that
foo(a, b) looks more familiar than
(foo a b) - plus, there's fewer commas and semicolons :)
Out of many many contenders, I focused on two:
I spent a month or so learning Reason and OCaml, but it felt that the ecosystem itself was much too young to be a robust platform, and even more crucially, the Standard Library story was just not there - it was not the goal of ReasonML to create and maintain a sane Standard Library for the web. Certainly though given the pace of development, it is worth another look in a year or so.
node_modules, ES2015 to ES3 transpilation (great for even very old browsers) and all the performance optimisations you can handle. In addition, the ecosystem has some top-notch developer productivity tool and has recently seen some major improvements in their interop story.
Soppy note: While writing this post I felt a bit bittersweet because I realised I'll probably won't use Python again in a production setting. Python was the language that propelled my software career and it does feel weird to be moving on. I would like to thank all the wonderful people that work on Python, and all the fantastic, caring and thoughtful community. You are the best!