When it comes to judging programming languages, there are three main factors that we need to consider: programmer productivity, the application feature set that can be implemented, and the runtime performance of the developed applications. There are, of course, many others, including memory usage, portability, and implementation cost. However, memory is plentiful these days, most languages have cross-platform implementations, and many of these implementations are free or have a low cost. So the three factors mentioned in the title become the most important ones.

I’d like to focus on the programming language transitions of the past few decades, in terms of those three factors, and in the domain of PCs and workstations. The first one we’ll consider is the transition from assembly to C. This trasition brought a significant increase in all of those factors. The use of C meant that it was easier for developers to rapidly create larger programs, while still running at nearly the speed of an equivalent hand-coded assembly program.

We witnessed a very similar transition slightly later on, when C++ often became favoured over C. We saw significant developer productivity gains due to the OO features of C++, which allowed for far more complex and featureful applications to be developed. While in some cases there was a slight performance drop relative to C, most C++ compilers emitted code that was very performant.

But then in the 1990s, things started to change. We had Java arrive on the scene in the middle of the 1990s. Compared to C++, Java did bring productivity gains, mainly due to its automated memory management. But unlike the previous transitions, it didn’t really bring anything inherent that allowed for more complicated or advanced appliation features to be developed. Most of its OO-related capabilities were already found in C++, or were otherwise easily emulated. Before the recent addition of generics to Java, the C++ STL also offered a much superior collections framework. Furthermore, we are all aware of the severe performance drop that Java brought in most cases. It’s only now, after a decade of research into Java-based JIT compilation (not to mention massive hardware improvements), that we’re beginning to find that it offers reasonable performance for desktop applications.

I think this trend is getting significantly worse with the rise of JavaScript-based Web applications. We really haven’t seen any significant developer productivity increases. Nor have we seen any real ability to create more advanced or extensive application features. These days, JavaScript developers spend a lot of time just replicating features that applications written in C, C++ or Java have offered for years. An example of this is all of the Web-based word processors and spreadsheet applications that we’ve seen developed. Even today, they are quite inferior to similar applications from the late 1980s and early 1990s. But perhaps worst of all, we’ve suffered enormous runtime performance losses. JavaScript applications often perform horribly, even on very modern hardware.

The lack of significant gains in those three areas really worries me. They’re key areas when it comes to developing viable, innovative, and quality software. What we’re seeing are actually several steps backwards, rather than one or more steps forward. Productivity is down, no new or innovative features are being developed, and application runtimes are suffering.

At this point, the only hope appears to be functional programming. Languages like Haskell and Erlang bring environments that encourage programmers to develop software in a far more efficient and productive manner. Likewise, they bring the language support necessary to develop new and innovative application features. Erlang, for instance, better allows developers to harness the power of multicore and multiprocessor systems, which also often leads to vastly improved runtime performance. And then there’s a language like Ocaml, which can be compiled to native binaries that offer excellent runtime performance.

The path of Web-based applications written in JavaScript is obviously one of failure. In terms of the key area of developer productivity, application feature innovation and runtime performance, it is clearly insufficient. And it’s doubtful that it will be able to overcome these problems without radical changes. So the only practical alternative at this point would appear to be functional languages like Haskell, Scheme, Common Lisp, Erlang, and Ocaml.