Robert J. Brotherus
Why so many languages?
Updated: Feb 7, 2022
Hundreds of programming languages have been born and died during the decades since 1940's. Some created by comitees, many by lone heroes, they have transformed the world.
The astonishing number of programming languages that have been developed during the years is exemplified by the fact that this list covers only about 1% of all programming languages existing or existed.
Evolution of languages
Original computers in the 1940's and early 1950's we programmed only in machine code if their respective processors, but when the development of higher-level languages began in mid 1950's with FORTRAN, the explosion of languages and their dialects has been staggering. The Programming languages genealogy-poster below shows some of the major languages developed between 1954 and 2001 with their predecessors and dependencies.
Like with any cultural phenomenon, the rise and fall of languages popularity is not - perhaps unfortunately - determined only by their relative merits. While some extinct programming languages are clearly limited and clumsy by today's standards, most currently used ones are "good enough" technically allowing other factors can significantly affect their popularity. One crucial factor is simply the feedback loop between language usage and programmer demand: there is more demand for programmers in popular language, this leads to more people study the language and more schools to teach the language, this leads to more companies adopting the language which in turn leads to higher demand for programmers. This can allow languages that are generally consider inferior to remain popular for extended periods.
Given the extreme importance of programming languages in todays world, it is remarkable how accidental their birth has often been, dependent on initiative and work of single heroes. Many major languages that have changed the world have been essentially created by a single person: Lisp by John McCarthy (pictured here), Pascal by Niklaus Wirth, C++ by Bjarne Stroustrup, Perl by Larry Wall, Python by Guido van Rossum, PHP by Rasmus Lerdorf, Ruby by Yukihiro Matsumoto and Clojure by Rich Hickey and many more. Such work has my highest respects: it has been shaping the landscape of computing. It is more rare for a language to be designed by a company or committee, notable exceptions including early FORTRAN designed at IBM and ALGOL which was created by a committee of computer scientists. While ALGOL did not become the permanent universal language that it was aiming to be, it was popular for a while and did influence many successor languages that are alive today.
The fact that new languages still pop up and rise to prominence from single-man projects is made even more remarkable by the fact that new languages needs to come today with a reasonably wide standard library of functions to be viable in competition. In the early days of Fortran, Algol, Lisp or even C and C++, you got only very basic function-library with the language if anything. Using such language required writing many basic components of your application from scratch. Modern languages like Java, C#, Python and Ruby come with extensive standard libraries for mathematics, collections, GUI, XML, security, databases, etc. plus vast collection of 3rd party libraries, greatly reducing the work of producing a working application. Some new contenders in the language-field like Skala, F# and Clojure, solve the problem by being based on the Java Virtual Machine (allowing use of the Java-libraries) or Common Language Runtime (allowing use of C# libraries).
Evolution of skills
Andy Hunt and David Thomas recommend in their great practical and inspirational book The Pragmatic Programmer that a good software craftsman learns at least two new programming languages per year. While I have not succeeded in quite as high a pace, it is true that continuous learning of new languages throughout ones career is beneficial (and enjoyable!). Bit surprisingly it can be beneficial even in case of new languages that one never ends up using professionally. Languages vary from imperative to functional to declarative, from object-oriented to data-oriented, from weakly to strongly typed, from dynamically to gradually to statically typed, from manifest to inferred typed, from interpreted to compiled, from message-passing to pattern-matching, from garbage-collected to explicitly managed, from curly-braces to homoiconic parenthesis, from stand-alone to runtime-hosted. Learning more and more languages is beneficial because it expands ones thinking which allows oneself to become better programmer even even in the languages one already knows.
When I learned F# in 2012 I had been using C# for 12 years already, but I started to write C# in more functional stateless way, leading to less simpler program flow and less potential errors from invalid program state. When in 2014 I learned Clojure with its common use of maps and lists instead of objects to store information, I began also reducing my unnecessary usage of classes in Ruby and Python in favor of more data-oriented approach, increasing re-usability of my code and ease of serialization of my data. It is good to have wide set of tools in ones toolbox of thinking and problem-solving. Programmers know a bad pattern of "Golden Hammer" when a novice developer is using just one language, one method or one way to solve all problems, leading to awkward and inelegant solutions in many cases. The saying goes: "If only tool you have got is a hammer, then everything looks like a nail to you."
But to learn a language one must use the language - not just read some articles and write a simple "Hello world" program. In working life, companies have usually significant investment in their current set of languages. This means that taking to use new language is a costly endeavor and not done commonly enough to serve these learning purposes of individual developers. It is here where hobby programming fills an important role. With hobby projects one can use new languages to make real applications. Hobby programming projects also don't have deadlines, so one is free to try to write the code in best possible way and rewrite parts of the code in better way as ones understanding of the language idiomatic ways in its libraries improve. And since the topic of hobby programs can be freely chosen they are guaranteed to be motivating in their targets and therefore fun to see the results. And even in those cases where such projects never get properly ready, they have been valuable on the way.
During the 37 years since my first VIC-20 there have been very few years when I did not have some hobby programming project going on along my studies or work. Some projects have been just fun games, some genuinely useful applications myself and some used and providing benefit even to wider range of people. Some topics have been recurring themes that I have returned again and again to re-implement with new languages and more elegant ways as my palette of technologies has expanded.
In search of the best language
Several times in the past I have encountered a new language that is exciting and powerful in some novel way and makes me think: "This the best language of them all!" The first moment was of course in the very beginning with the VIC-20 Basic since I knew nothing else and the language seemed suitable for everything. It also happened in 1988 with Turbo Pascal which had great structured types compared to the simple arrays of Basic. And in 1993 Borland Delphi gave me both Object-Oriented programming and so simple creation of Windows GUIs that I fell in love immediately. Later love-affairs were formed in 1996 with Mathematica (aka. Wolfram Language) for its functional and pattern-matching power, in 2007 with Ruby for it's concise dynamic power, in 2010 with F# for functional programming and type inference and finally in 2013 with Clojure for it's dynamic functional programming, LISP-inherited metaprogramming and immutable state-management. In between these moments I have done also much work with Fortran (with zero danger of love-affair) and the mainstream languages Java and C# (which have been good friends but did not cross the "best language ever" threshold).
More difficult can sometimes mean more powerful, but there are also
accidental unhelpful aspects of difficulty. From XKCD :
Having experienced several times the feeling of "Wow, this is the one true language, I will use it forever!" has of course made me more humble for the possibility that perhaps my latest language love is still not the greatest of all but there might be yet more wonderful possibilities (present or future) that I am just not currently aware of. So although Clojure is in my favor and I have been able to accomplish with it elegance, simplicity and robustness higher than with my earlier lovely languages, I definitely don't want to rule out the possibility of even greater greatness, especially with future innovation.
Time and place for every language?
Flame-wars between proponents of different programming languages erupt occasionally in the internet and preferences can be rather personal. There are several counter-arguments to an extreme preference of one language over another, though their validity vary. First, it can be said that most modern popular languages are "good enough" and differences in productivity are not significant. While this is certainly true for small to medium-size programs, the validity of the argument is less clear in large-scale or special-purpose programs where the differences in languages support for eliminating incidental complexity (complexity not related to the application-problem itself) can become more significant.
Second, it is argued that instead trying to find single best language, one should pick best language for a particular purpose and if a large-scale program involves multiple purposes, allow multiple interacting languages (so-called polyglot-programming). This can be valid in some cases, especially if some purposes depend on libraries available only in some languages (high-performance math as an example). But one should keep in mind that of the many large systems that use multiple languages, most cases are likely to be accident of history and not represent a planned polyglot-strategy. Also the cost of interoperating between multiple languages gets rapidly higher as the number of language-pairs rises as the square of the number of languages, though a microservices-architecture with standard interfaces can alleviate this problem.
Third, in the new version of existing languages, successful features from other languages are often added, blurring the distinction between languages. For example developers using Java, C# or even C++ have seen in recent years a delightful "arms race" of features being copied from other languages. Things like type-inference, lambda-expressions, first-class functions, dynamic typing and pattern-matching are being brought to these mainstream languages from more niche languages. Such development benefits all parties and evolves languages to be better and more similar. But because languages typically keep all old features as well for backward-compatibility, the continuous adding of features makes the language more complex year by year. This can be seen by the increasing burden of legacy features in new versions of old work-horses like C++ and Fortran, but is also becoming visible in middle-age languages like Java, Python. Hence there is still need for the occasional fresh start, creation of new well-designed languages like Ruby, Clojure and Rust where some subset of best modern features are taken in but old baggage left out.
The wonderful Tao of Programming concludes:
Thus spake the Master Programmer: Each language has its purpose, however humble. Each language expresses the Yin and Yang of software. Each language has its place within the Tao. But do not program in COBOL if you can avoid it.☺