Analysis and comparison of 20 of the most used programming languages in 2020
What are the most modern, or at least adopted, programming languages in 2020? And how do they compare on the most acclaimed features programmers usually look for in a programming language nowaday?
Share your comments to this article on reddit.
Introduction
Programmers discussions about who is working with the most gifted programming language have a long tradition, and they often turn into one of the most passionate religious wars in programming. Envious because our friend's language has already adopted that new paradigm or sugar syntax or its runtime performance just got a big time improvement recently while our language seems to fall behind, we embrace infinite confrontations between languages often purely based on subjective tastes and preferences that nothing have to do with the reality of the facts.
In this long article I still express plenty of my personal tastes and preferences (let the wars begin!) and yet before my opinions I list the same series of real facts for everyone of the 20 programming languages I analize so that everyone can make their own informed opinion.
How I chose the languages
I chose the languages that:
-
have a syntax derived from C/C++, since I like and prefer C-like languages, and are modern languages or at least very popular: C/C++, C#, Ceylon, D, Dart, Java, Swift.
-
are too popular or have a very passionate community to ignore them: JavaScript, PHP, Python, Ruby.
-
are very young and everyone is talking about them (in programming a language that is less than 10 years old is very very young): Go, Kotlin, Rust.
-
for some reason I have studied and tried to adopt them many times during the years and so I had something to say about them: Groovy, Haxe, Nim, Scala, TypeScript, Xtend.
Notable languages also present at very high positions in the TIOBE index that I excluded are merely absent just because I really know too little about them to include here. Examples are Visual Basic and R.
List of the 20 languages chosen for the battle, in strict alphabetical order:
C/C++, C#, Ceylon, D, Dart, Go, Groovy, Haxe, Java, JavaScript, Kotlin, Nim, PHP, Python, Ruby, Rust, Scala, Swift, TypeScript, Xtend.
But wait, before entering the arena let me present you which criteria I used to prepare the languages cards.
What programming language features I collected and why
I collected three groups of data for every language:
- Real facts.
- Target platforms.
- My rating and notes.
Real facts
One of the most intriguing things that emerged when I started making this analysis was that it's actually not very easy to establish on what specific characteristics to compare programming languages often very different one from each other. In the end I decided for this method. First: I made a review of the characteristics of each of the languages as presented on Wikipedia, and then on the official languages websites. For each of the characteristics encountered, I asked myself: if I were a programmer (which in fact it happens I am!) would this characteristic matter to me or is it something that has little or no value to me? Everything that I found desirable I included among the characteristics to be investigated, the rest I ignored. Second: I checked my preferred programming lanaguages and I listed what I was missing in them and I would like to see implemented. Now the list was complete, I had 28 pieces of information to collect for every language, which was not easy at all.
Before describing all 28 collected information however I have to make two clarifications. First: the reason why I describe in detail the meaning of each of the 28 characteristics is because as a matter of fact programming languages are still a very new thing for us humans, and the meanings, as well as the implementations of course, even of the most basilar porgramming concepts varies a lot from language to language. Second: designing programming languages is hard. Errors in their making are made all the time. Some of these errors resound for decades in the DNAs of the languages causing huge amount of pain for milions of programmers (Java I'm looking at your rejection of getteres and setters, Python I'm looking at the amount of self in your programs, etc.). Other errors however are so big that cause the premature death of a new programming language. While it is often not easy to know before the fact what errors will really come out to be errors and what not, I still decided on my own what current trends in programming languages are bad or pointless and so I excluded from the features to collect. One such notable case is for me the well known madness about the null safety that is so much flaming in recent years. This is not the right place to explain why I'm against it, maybe one of these days I will write an article exactly on this matter. Here I just say that what is being implemented to avoid the small problem of nulls is causing pains 10 times bigger to comply to. So no, null safety features are not a thing in the evaluation of a programming language as per my opinion and that's why you won't find it listed here. The same is probably for other things you could find missing: I excluded them because I simply don't believe in them or because they are not desirable for me. Or maybe because I simply don't know about them. While I love programming languages and I constantly study about as many of them as I can, it's possibile that there is something in the field that I still don't know.
Anyway, without further ado, here are the descriptions of the 28 features I chose to collect.
Type system
The #1, most important, crucial feature of any programming language is the type system that it adopts. Many new programmers have a hard time to understand how much foundamental this aspect is. A book, and a big one, could be written only about this topic. That's why this is the first piece of information I collect for every language. To give to newbie programmers some pragmatic takeaways about the topic I summarize it this way. There are two main typing systems, static and dynamic. Static is when a language forces the programmer to know almost every moment what type of object the code is dealing with. Dynamic is when there is no way to know what kind of object the code is dealing with until the application gets debugged, that is the application has already been written and is now running. Static type system languages are heavier to program with, are much more verbose and require more careful and complex designs. This is why new programmers usually dislike them. On the other side a static type system increases a lot programmers productivity when what is being written is big, complex, and is being developed using a modern IDE instead of a common text editor. That's because a good IDE helps a lot to mitigate the necessity to remember methods, variables and so on. Pratically the IDE writes on it's own at least 50% of all characters of source code. The static type system moreover allows many errors to be caught at compilation time instead of runtime which means that during execution a program is way less prone to show bugs and malfunctioning. Most errors that can be done in programming are simply impossibile to be done with a static type system language.
Dynamic type system languages on the contrary are much lighter, cheeky and quick to program with. With them you can put a lot more creativity and fun in your programs. Still you're totally alone. IDEs cannot help you, they cannot guess what kind of objects you're dealing with. Compilers cannot know if this or that method or property is really part of this or that object. Nothing is known before the program runs. This is also why usually compiled languages are static type system languages, while interpreted ones are dynamic. That means: scripting languages have usually dynamic type systems, programming languages usually static. If people could just remember only this fact, many problems would never rise in programming. Scripting is a thing, and a dynamic type system is ideal when scripting. Programming is another thing, and a static type system is really not an option if you are serious about programming. Even just knowing this and only this, you will always choose the right language when starting a new probject. Problems arise when people want to use scripting languages for programming... but that's for another article.
Type inference
Since a static type system language is heavier to program with and is much more verbose, one day language designers started wondering if there could be some ways to mitigate the static type system disvantages without loosing its strenghts. The results of this wondering, trying and designing are here (and in many other places) collectively called Type inference, which means that a language has explicit constructs, syntactic sugar, tricks and escamotages to free as much as possibile the programmer from the continuous need to specify the types of objects she's using while still giving IDEs and compilers a way to make the right guess about the types. For example, consider this Java code:
Which is shorter indeed, and yet gives IDEs and compilers a way to infer the type of variable foo
just by looking at what is being created and assigned to it.
Of course for dynamic type system languages this feature doesn't make any sense, in those cases I will just label it with not applicable.
Automatic memory
Another crucial feature of any programming language is if it automatically manages on it's own the allocation and the freeing of memory or if it forces programmers to make this manually on their own. This is very often a synonymous of the question: "Has this language a garbage collector?" So why is this feature so important? Well, decades of programming teached us that managing memory manually for big and complex applications is not only very hard, but gives also birth to a type of bugs which are really hard to discover, understand and remove. To be honest today there are many tools that help in monitoring and solve manual memory management problems, still the manaul allocation and freeing of memory remains very critic, prone to errors and time consuming at the point that very rarely the advantages that it offers are worth the hassles it causes in contrast to automatic memory management. So why is this still a thing in 2020 and people don't just use automatic memory all the time and bye bye the manual way? The answer lies in the fact that still today automatic memory management has always some costs and there are applications that can't afford those costs. Automatic memory management most of the time means that there is a Garbage Collector, and this kind of software still need today pauses, sometimes prolonged ones, to make their job. Imagine a civilian plane that is performing an automatic landing and in the middle of the maneuver the onboard computers have to take a generous pause of a few seconds to free up memory. Not only. Without reaching such extreme cases, also imagine the case in which the plane is simulated and you are in a video game doing an aerial battle. Well, you would probably give up soon playing a game that stops here and there during the best moments of the action just because the garbage collector needs some seconds to free the memory.
Now, I have strongly emphasized the problem here.
While two decades ago these multi-second garbage collector pauses were absolutely not rare, I've personally witnessed 90 seconds and plus paues in production servers under not even very heavy load, today things are widely different. It's years now, at least with Java and JavaScript, since I last noticed a garbage collector pause, even in video games. I still won't use garbage collectors if I had to develop software for real planes or nuclear implants, but I surely would go with it for 99% of all the other kinds of applications, that's why for me, and the type of software that I develop, a language that offers automatic memory management is a must.
Assertions
A language should have assertions. Point. I won't go further on this here because assertions is an old concept in programming, on which it's very hard to have different opinions, there is nothing controversial or still not understood or to better evolve about them. Just read on wikipedia what they are if you don't know. In an ideal world every language would have assertions, instead there are languages that don't offer them, so I had to collect this information too.
Object oriented
This is another programming concept that seems to be strongly consolidated nowaday, even if it's often implemented in very different ways. Yet fortunately there is still innovation in this area too. Read on and discover what language is doing it in a very original way.
Multiple inheritance
Java coined the concept that multiple inheritance in OOP is bad for you. Unfortunately almost all the programming languages that have been invented after Java follow this approach even because many of them are made for the JVM and this does not support even at low level multiple inheritance.
I am deeply against this aversion to multiple inheritance. This has only one single problem, which to be honest is not even a problem at all, it's just a characteristic, and still among other ways they even call it the "Deadly Diamond of Death". I think that the only Deadly thing you can find in this context are the neurons of those who invented this war against multiple inheritance which I truly classify as a perfect example of one of those huge mistakes about which I talk in Real facts that usually afflict a language for decades. In this case the error went even viral afflicting many other programming languages despite
Bjarne Stroustrup, the inventor of C++ which of course offers multiple inheritance, and many other great programmers had explained times and again in many interviews how and when multiple inheritance is really something that help programmers express and mantain better their code in many real cases.
Fortunately new languages that don't depends on the JVM or the CLR (which made the same error) are starting to apper again with support for multiple inheritance. Not only, the same Java at some point had to face the reality of how much usefull, even necessary, is to support multiple inheritance and in fact it now allows and implements it, even if still only for interfaces default methods.
To cut it short, I want to know if a programming language supports the very good and desirable feature of the multiple inheritance, hence I collected this information.
Prototype extensions
So you won't find on internet an easy and correct explanation of what is the feature that I call Prototype extension for two reasons:
-
it is wrongly associated with prototype-based OOP languages like JavaScript as opposed to class-based OOP langauges like C++, Java and the like.
-
while many will find logical to see this feature implemented in dynamic type system languages it is possibile and is already being done to implement it even in static type system languages, even if to be honest this started to be made only in recent years.
Prototype extensions, as I intend it here, is the possibility to extend a class from outside itself, meaning that you can add methods, fields, even entire interfaces to classes that you probably don't even wrote yourself to begin with, and if possibile even directly at runtime, and yes, even with statically typed programming langages.
I know this is still today a bleeding edge feature of programming and surely an advanced concept with which many are still unfamiliar. Still many uses it in JavaScript and others experience it in languages like Kotlin. I've tried it in many occasions and with different languages and I like it a lot. I collect this information hoping that it will improve, extend and be offered by more and more languages.
Instance extensions
This one is truly esoteric and probably I've invented it myself because I've not found a common definition of it despite being implemented by some languages.
What I intend with Instance extensions is the possibility to add a method or a filed to an instance of a class without modifying its class. This is made very often in JavaScript, Python and in general in every dynamic type system language. Still I think it should deserve a place even in statically typed languages. I decided to collect this information too when I discovered that there is at least one programming language which has a static type system and yet it offers this feature too. Hooray!
Generics
Personally I first came in contact with Generics with templates in C++. They are not really the same thing. Java in fact introduced them later and only as a sort of simulation of the C++ templates. If you want to know more I suggest wikipedia on the topic. Here it's enough to say that once you get used to them you don't want to give up on them. Of course this is a feature that makes sense only for static type system languages, for the others I'll just label not applicable.
Annotations
Same with annotations, once you started using them you want them all the time. Now, Annotations still don't have a standard, unique name in all languages, in fact they call them Attributes in C#, for example. Anyway with annotations you're given the possibility to annotate, which means add some extra static information to, classes, methods, even arguments of methods and so on. This additional data it's usually possibile to be used during compilation or even retain at runtime. Annotations are a very welcome additions in modern programming as I see it. With them you can make many things some of which I list here:
-
define service contracts to expose web sevices API
-
map classes to database schema
-
give additional information to programmers (Ex.: @NotNull)
-
give hints to tranpilers when code is converted to other platform (Ex.: transpile Java to JavaScript)
Union types and Intersection types
I've personally seen these kinds of types for the first time in TypeScript. Normally I would not love them too much, I can live with a programming language that don't offer them. Still I understand why TypeScript has them, because they help the language in one of its main goal: give JavaScript the opportunity to be used as a static type system language.
In fact anyone who has ever programmed in JavaScript knows that the code is full of things like these:
Which produces this output:
These happens because not having JavaScript types the nature of the passed arguments should be determined at runtime. On the other side being TypeScript's first goal that of adding types to JavaScript it could not accomplish its task in cases like the one above if it hadn't Union types.
With them the above code becomes in TypeScript:
With the important difference that the last doSomething(()=>{});
in TypeScript would result at compilation time in a message to the programmer highlighting that something wrong is being done. The doSomething
function in fact doesn't accept the function type, it only works with strings, numbers and objects. This also clarify very well what's the difference between a dynamic type system language and a static one. In the dynamic one (JavaScript code) not only you can pass a function ()=>{}
to a method that doesn't want it, which is already an error in its own, but you should remember to handle this situation inside the method and emit the text arg is something that I don't want (a function?)
otherwise it would be very hard for the programmer to understand what's happening and where and why the code does not work. Anyway all of this still would happens only at rumtime, while the code is running, probably on the machine of your customers while you are away and could not even give a look at the logs. With static type system languages all this never happens. After you specified the types, the compiler handles all the cases at compilation time for you. Way less problems at runtime.
So, again, if you're just writing a few lines of code to animate a couple HTML elements, aka: you're scripting, go with JavaScript, it's easier, lightweight, cheeky, and fun, and the errors that could arise in such kind of scrips are easier to find because there are just a few hundred lines of code at worst. If you think to write your next 3,000 features, 1 milion plus lines of code, node.js mega-server-platform with JavaScript, sorry I wouldn't employ you in my next startup not even if you were the last programmer on planet Earth.
Intersection types are a little bit different, and to be honest they are the ones that should have been called Union types. The undurstand them I thing it's best to read about them on the TypeScript website here.
Apart for their names which should have been exchanged with each other, Union types and Intersection types are useful advanced types in a modern language especially if one wants the language to be transpilable to Javascript, hence I collect these two too for all the fighetrs of this battle.
Alias of types
Sometimes aliasing types is really useful hence I include also this info. The war against aliasing is again something strongly promoted by Java, which in fact does not offer it. It's another war against windmills with which I don't agree at all.
Functional
Discussing what is Functional programming here is out of scope. I collect this info for you for all the languages, you learn about it on Wikipedia. 😎
Higher-order fn
Higher-order functions are a must in programming. We like them, we want them, we collect this info!
Exception handling
There were dark days in the history of programming when Exception handling was implemented only in Lisp and lacked in other mainstream programming languages for decades, or was offered only in some restricted version. Still today Exception handling is a controversial topic in programming and implementations vary widely. Personally I'm not a fan of the Java variant called Checked exceptions, and I understand some criticism usually made to exceptions because they confuses the control flow of executions. It's also true that sometimes it's not so easy to decide if something bad should be treated as an error or an exception. Despite this, I remember the times when software was developed without any form of Exception handling and honestly I don't want to see it again.
Operator overloading
Let's put this very simple: a language which refuses to offer programmers a way to rewrite what happens with +, - and all the other operators usually available in any programming languages immediately puts itself as a enemy of matematicians, 3D programmers, AI hackers, and everyone who work with complex numbers, matrices, vectors and the like. Do we really want to be their enemies? Not at all! We like Operator overloading, we want it, we collect and list this info for all the languages and we are happy with those of them who offers it.
Custom get/set
A language that offers getters and setters facilities for class attributes frees programmers from the heaviness of traditional set and get methods. Where before you had to type setFoo(...)
and getFoo()
, with getters and setters you just type foo=...
or just foo
to get it and the relative setters and setters are automatically executed . Not only this greatly lightens programming, improves readability and streamlines code, it's also semantically way more correct and consistent with the nature of what one is really doing: modifying or reading an attribute, not explicitly willing to call a method.
So why don't all languages offer this feature? Because the detractors of this functionality claim that when a programmer writes foo=2;
, for example, she expects 2 to be placed in a memory location, with all the consequences attached, i.e. that the execution of this operation is as fast as it would be in C, and it is unquestionable, nothing can prevent that 2 from being really put into foo
. Writing that same code when there is a setter, instead, the operation would not only consist in a much slower execution of a method (the setter) instead of a quick assignment, something that the programmer may not even be aware of, but moreover nothing prevents the setter from doing something other than simply putting 2 into foo
, that is, the programmer cannot even be sure that what she has programmed is done exaclty as she intended.
Personally I find these observations totally nonsense. First: yes something different from what the programmer intended could happen with setters and getters, but that's exaclty what sometimes is needed. Consider the class:
I don't want a programmer to set age
to a negative number. Without a setter however I have no way to check this. Not only. While technically speaking a language can implement class attributes that are readonly, without getters and setters things get weird fast: if an attribute is readonly how can I put something in it? With getters and setters, on the other hand, I can customize access modifiers for get and set methods. Maybe internally a class can set a value because the setter is configured to have private access but others cannot, the getter instead could be set public for all to read the value. The other observation, that setter and getters are slower and a programmer could not know her code is incurring in a speed penalty, is nonsense too. If a programmer don't know how the language she uses works I have big doubts that this would be the only thing to confuse her.
To conclude, we like getters and setters. We want them! We collect this info too.
Multithreading
Multithreading is when in a single program you run all together many different subprograms simultaneously. Imagine you want to make a birthday cake: one makes the sponge cake, at the same time another one makes the cream, another one is organizing the decorations, while the last one is shopping for the candles. What a wonderful thing is multithreading!
Unfortunately, however, multithreading involves major programming complexities. In the case above imagine if the person who makes the cream puts it before the sponge cake is ready, the one with the decorations collides with the one who is pulling the sponge cake out of the oven and the last one with the candles light them on the way back instead of when the cake is served. Disaster!
For this reason, during the decades, multithreading has been the victim of brutal rejections and attacks, neverending religion wars, fierce accusations of being the worst evil ever faced in computer science, the source of irreparable litigations and defintiive divisions between the biggest eminences and gurus of the programming world.
So deep were the contrasts in some cases that even some very widely diffused OSes in the server arena took 10 years to finally support and implement the POSIX Threads specification, which in IT world means they were a thousand years late.
Still today multithreading is a very hot and controversial topic on which it seems that people really can't reach a consensus. The main question is the same from 20 years ago: should a server respond to a request spawning a new process (node.js) or using a different thread (Java)?
Personally I totally agree with the fact that multithreading is very hard to be done cocrrectly, and introducing hard to eradicate bugs with it is almost inevitable. Not only. I also agree with the fact that most of the times you think you need multithreading there is a safer and more effective way to do it without multithreading. Having said that, I am not from the school that it's better to launch new processes than other threads. I have already my db connected, my program running, my data setup, my processing ongoing, etc. Honestly, I understand that starting a new process and repeating all that is way easier because after all you already programmed those things, and doing so you avoid a lot of multithreading hassles, but performances and resources are wasted big time this way, sorry I'm not from this school. I want a programming language that gives me the tools to write multithreading software when I really need to. I can't accept missing them.
Coroutines
In programming there are very few concepts that are really new. Usually one comes across old things that come back to the fore maybe in a new and unexpected way. Coroutines fall fully into this category.
In wide use today thanks to JavaScript, coroutines are an example of a good option one could have to avoid multithreading. In fact with them it's possible to execute different tasks on the same thread switching the execution point from one part of the code to another and back and fort. Usually this features emerges in programming langauges with keywords like yield, async, await, and work in tandem with so called arrow (or lambda) functions etc.
We like all this. We think a modern language should offer them.
Closures
We want closures too, that's for sure!
They are when you write code like:
and inside returnFn
yuo can use the variable a
even if it's not defined inside returnFn. That's to quickly remind you what they are. If you need more details I suggest a visit to Wikipedia.
Multiple returns
Many will think that not having Multiple returns support at language level is not all that tragedy after all. I agree on this, we can live without, we just use a list, an array or whatever if multiple returns is not available and problem solved. Still they are fun to have, so why not?
String templates
Some call them String templates others String Interpolation, no matter the name, this is a very welcome feature. Here is a quick example of what we are talking about:
Multi-line strings
Also called Multi-line string literals, one could expect that in 2020 no language should have problems to offer an easy way to insert multi-line strings in code, especially because nowaday it's very commond to make complex templating and text processing in general (HTML templates tells you something?).
Well, turns out not every language has this. Let's collect who does.
Collections
Ok, this one is probably just my hairsplitting, every languages offers arrays, lists, maps, etc. Maybe via libraries or built in their standard library, but everyone has these. What I'm looking for here, however, is if the language has special costructs built in the language that greatly help programmers populate, manage and manipulate in general such objects. On this front Python is a great example of what I mean, as well as Scala and also others.
Preprocessor
I've always been a multiplatform developer and good preprocessor facilities are a godsend in this context. Yes I know that with annotations and the like many things can be done without any preprocessing at all. Still sometimes a couple compiler directives ala good, old-fashioned C way are all that I ask for.
License and Inventor(s)
I'm sure you can figure out for yourself what these two info are about. 🤗
Target platforms
In a perfect world if a language tells you that it will get you writing code once and run it anywhere, one could never imagine that with anywhere they didn't intend also the most sold phone in the world or the most used app of the world (browser). Unfortunately this is far from a perfect world and supporting as many target platforms as possible for a language turns out to be more a political and commercial matter than a technical one. This is why for example you see things like nonsense GraalVM that tries to bring all the world on the JVM while the world itself is in an hurry to jump on the browser and WebAssembly bandwagon where Java is not even a thing.
Apart from that, I think that multiplatform development is mandatory, probably today even more than ever, especially because of the very WebAssembly stuff. As the world totally agreed that the browser became the center of the interaction between humans and services, I truly thing that it will finally agree also on the underlying execution environment for apps once and for all, after decades of messness and fights. That execution environment will be WebAssembly because it gives both of the two most important things every platform vendor looks for: they can remain themselves and offer unique and exclusive experiences to their customers without loosing their footprint (with their OS), and at the same time never risk to slip outside the center of the platform users will most of the time interact with (WebAssembly).
Anyway these are just speculations and fantasies for the future. A programmer should be pragmatic and always look also at what is available today that supports her needings. This is why I've selected the 9 platforms that I believe are the most relevant today and I've listed for each language for which of those targets it can be used.
My rating and notes.
Probably I should say "My ranting" instead of "My rating". Hahaha joking. But not too much. Ok, so the point here is, I started this study for a very specific needing of mine, but doing it I discovered way more of what I was looking for. I will add some final note on this in the Conclusion section below. Here suffice to say that I got a strong feeling that too little is moving in languages and tools for software development. Therefore I went down hard and said what I really think for each of the analyzed languages. As you will see, no one of them took the best rating (5).
And now... to the cards!
C/C++
Features | Targets | ||
---|---|---|---|
Type system | static | JVM | no² |
Type inference | partial | CLR | yes |
Automatic memory | no¹ | JavaScript | no³ |
Assertions | yes | WebAssembly | yes |
Object oriented | yes | Windows | yes |
Multiple inheritance | yes | Linux | yes |
Prototype extensions | no | MacOS | yes |
Instance extensions | no | Android | yes |
Generics | yes | iOS | yes |
Annotations | no | ||
Union types | partial | ||
Intersection types | no | ||
Alias of types | yes | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | yes | ||
Custom get/set | no | ||
Multithreading | yes | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | no | ||
String templates | no | ||
Multi-line strings | yes | ||
Collections | no | ||
Preprocessor | yes | ||
License | there are closed and open source implementations | ||
Inventor(s) | C Dennis Ritchie, C++ Bjarne Stroustrup | ||
My rating (0-5) | 3 |
My notes: C is the father of all programming languages as I see it. C++ is its OOP evolution. So when you resort to a father? I think when everyting else is not enough. When you do, anyway, you probably know that this is a severe language. You are not supposed to misbehave or be light and shallow when you program in C. To all that C++ adds more heaviness, complexity and verbosity, but also offers much wider possibilities for software design. Unfortunately it does not free the programmer from annoying stuff like memory management and so on. Again, these are languages one resorts to when there is really no alternative to them and all their power is really needed. For me, when this happens, one should wonder why in 2020 we still don't have something as powerful as C/C++ and as funny as many other less low level programming languages.
1. Libraries that implement garbage collection for C/C++ programs exist, but they are not part of the language or the language standard library.
2. with GraalVM C/C++ code can be compiled to LLVM bitcode which can then be executed on the GraalVM Java virtual machine.
3. C/C++ can be transpiled to JavaScript, however the preferred way to run C/C++ programs in the browser nowaday is to compile it for WebAssembly. JavaScript target was used when WebAssembly was still not available or was still experimental.
C#
Features | Targets | ||
---|---|---|---|
Type system | static | JVM | no |
Type inference | yes | CLR | yes |
Automatic memory | yes | JavaScript | no¹ |
Assertions | yes | WebAssembly | no |
Object oriented | yes | Windows | yes |
Multiple inheritance | no | Linux | yes |
Prototype extensions | no | MacOS | yes |
Instance extensions | no | Android | yes |
Generics | yes | iOS | yes |
Annotations | yes | ||
Union types | no | ||
Intersection types | no | ||
Alias of types | yes | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | yes | ||
Custom get/set | yes | ||
Multithreading | yes | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | no | ||
String templates | yes | ||
Multi-line strings | yes | ||
Collections | library | ||
Preprocessor | yes | ||
License | Open source | ||
Inventor(s) | Microsoft | ||
My rating (0-5) | 3 |
My notes: Honestly I never understood why one would use C#. It's like Java plus minimal improvements less the real extraordinariness of Java: that of being truly cross-platform. C#, .NET, the compilers and all the rest could even be open source, as they infact now are almost all of them, but the juiciest parts are still today (2020) only implemented for Windows (WinForms, etc.). The only exception is for game engines. Many of them are scriptable with C# and the portability to other platform is made by the engines themselves. So, yes, that's one of the places I see C# fits well.
Ceylon
Features | Targets | ||
---|---|---|---|
Type system | static | JVM | yes |
Type inference | yes | CLR | no |
Automatic memory | yes | JavaScript | yes |
Assertions | yes | WebAssembly | no |
Object oriented | yes | Windows | no |
Multiple inheritance | no | Linux | no |
Prototype extensions | no | MacOS | no |
Instance extensions | no | Android | no |
Generics | yes | iOS | no |
Annotations | yes | ||
Union types | yes | ||
Intersection types | yes | ||
Alias of types | yes | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | no | ||
Custom get/set | yes | ||
Multithreading | from hosting environment | ||
Coroutines | no | ||
Closures | yes | ||
Multiple returns | no | ||
String templates | yes | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | no | ||
License | Apache License 2.0 | ||
Inventor(s) | Gavin King | ||
My rating (0-5) | 1 |
My notes: Too few platforms targeted, sorry not for me.
D
Features | Targets | ||
---|---|---|---|
Type system | static | JVM | no¹ |
Type inference | yes | CLR | no |
Automatic memory | yes | JavaScript | no |
Assertions | yes | WebAssembly | no¹ |
Object oriented | yes | Windows | yes |
Multiple inheritance | no | Linux | yes |
Prototype extensions | no | MacOS | yes |
Instance extensions | no | Android | yes |
Generics | yes | iOS | yes |
Annotations | no | ||
Union types | partial | ||
Intersection types | no | ||
Alias of types | yes | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | yes | ||
Custom get/set | yes | ||
Multithreading | yes | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | no | ||
String templates | no | ||
Multi-line strings | yes | ||
Collections | no | ||
Preprocessor | no | ||
License | Open source (Boost) | ||
Inventor(s) | Walter Bright | ||
My rating (0-5) | 3 |
My notes: When I discovered D many years ago it seemed to me very good. The point is that I want the WORA promise finally come true. D is not even close to that. Today if you don't target the web you're not for me.
1. Probably yes because there is also an LLVM-based compiler and with that teoretically it could be possbile to port D programs both on the JVM (with GraalVM) and WebAssembly. But nowhere on the dlang.org website these things are said.
Dart
Features | Targets | ||
---|---|---|---|
Type system | static | JVM | no |
Type inference | yes | CLR | no |
Automatic memory | yes | JavaScript | yes |
Assertions | yes | WebAssembly | no |
Object oriented | yes | Windows | yes |
Multiple inheritance | no | Linux | yes |
Prototype extensions | no | MacOS | yes |
Instance extensions | no | Android | yes |
Generics | yes | iOS | yes |
Annotations | yes | ||
Union types | no | ||
Intersection types | no | ||
Alias of types | yes | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | yes | ||
Custom get/set | yes | ||
Multithreading | yes | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | no | ||
String templates | yes | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | no | ||
License | BSD | ||
Inventor(s) | Lars Bak, Kasper Lund | ||
My rating (0-5) | 3 |
My notes: Dart makes me angry. I like a lot Dart, but... Really I would settle with Dart. It's almost 100% identical to how I've always imagined my dream programming language would be. Still I won't adopt it and that's for two resons. First: I gave a quick look at the Dart library about HTML and I immediately noted one thing: HTML elements have the property text
which, as I saw in a sample code, is clearly the standard Web IDL property innerText
. Why, oh why, really WHY??? change a standard which is incredibly universal and used in the whole world and took years of many many many people put togheter to get there? I immediately read that as an attempt to lock programmers in the Dart version of the web. Sorry, I can't stand this. Second: in 2020 we programmers are all used to work with powerfull editors to write code also because they are able to automatically format the code the way we like. If there was not such a formatter for Dart... well, ok, it's a young language, I would have understood, and I would have resorted to some alternative from other languages or even evaluated to write one my self. Unfortunately the real story is totally different and quite impossible to believe: Dart has it's own code formatter, and a very complete and sophisticated one to be honest, but... TADA... it's FIXED!!! As by the official code conventions of the language programmers are not supposed to be able to decide on their own if {
should be put on the same line or the next, not how much tabs are big or if they are really tabs or spaces. Years of progress to get to the wonderful automation of code formatting thrown down the toilet for the sole reason that this way any discussion about the coding style in any open source project gets automatically ridded by the fact that anyway you cannot format the code the way you want. It had been years since I had come across a decision of such a huge level of idiocy. I even politely expressed my opinion in a thread on GitHub where also other programmers are complaining about this madness, you can find it here.
Now, one would think that an intelligent IDE would ignore this monstrosity and would give its users the ability to setup the formatter the way users want. Well, guess what? No, it's not this way. Not at all. Why? Well, maybe because the best IDE of the world is made by the same company that has all the interest of this world to discourage people to adopt Dart since they developed an alternative language which has 100% the same goals of Dart? Guess who I'm talking about!
Go
Features | Targets | ||
---|---|---|---|
Type system | static | JVM | no |
Type inference | yes | CLR | no |
Automatic memory | yes | JavaScript | no¹ |
Assertions | no | WebAssembly | no² |
Object oriented | yes | Windows | yes |
Multiple inheritance | not even single | Linux | yes |
Prototype extensions | no | MacOS | yes |
Instance extensions | no | Android | yes³ |
Generics | no | iOS | yes³ |
Annotations | no | ||
Union types | no | ||
Intersection types | no | ||
Alias of types | yes | ||
Functional | no | ||
Higher-order fn | yes | ||
Exception handling | no | ||
Operator overloading | no | ||
Custom get/set | no | ||
Multithreading | yes | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | yes | ||
String templates | no | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | no | ||
License | BSD-style + patent grant | ||
Inventor(s) | Robert Griesemer, Rob Pike, Ken Thompson | ||
My rating (0-5) | 2 |
My notes: Sorry, for me this language is a no go. It has too few features.
1. But see gopherjs.
2. Go 1.11 added an experimental port to WebAssembly. Go 1.12 has improved some parts of it, with further improvements expected in Go 1.13.
3. See golang/go Mobile.
Groovy
Features | Targets | ||
---|---|---|---|
Type system | both static/dynamic | JVM | yes |
Type inference | yes | CLR | no |
Automatic memory | yes | JavaScript | no |
Assertions | yes | WebAssembly | no |
Object oriented | yes | Windows | no¹ |
Multiple inheritance | no | Linux | no¹ |
Prototype extensions | yes | MacOS | no¹ |
Instance extensions | no | Android | no¹ |
Generics | yes | iOS | no¹ |
Annotations | yes | ||
Union types | no | ||
Intersection types | no | ||
Alias of types | yes | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | yes | ||
Custom get/set | yes | ||
Multithreading | yes | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | yes | ||
String templates | yes | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | no | ||
License | Apache License 2.0 | ||
Inventor(s) | James Strachan | ||
My rating (0-5) | 2 |
My notes: Groovy is a good scripting language for the JVM and the Java echosystem in general. Sorry, I can't see more than that in Groovy.
1. Being compiled to JVM bitcode, Groovy programs can potentially be compiled to native executable with GraalVM.
Haxe
Features | Targets | ||
---|---|---|---|
Type system | static | JVM | yes |
Type inference | yes | CLR | yes |
Automatic memory | yes | JavaScript | yes |
Assertions | yes | WebAssembly | yes |
Object oriented | yes | Windows | yes |
Multiple inheritance | no | Linux | yes |
Prototype extensions | yes | MacOS | yes |
Instance extensions | yes | Android | yes |
Generics | yes | iOS | yes |
Annotations | yes | ||
Union types | no | ||
Intersection types | no | ||
Alias of types | yes | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | yes | ||
Custom get/set | yes | ||
Multithreading | yes | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | no | ||
String templates | yes | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | yes | ||
License | GPL 2.0, library: MIT | ||
Inventor(s) | Haxe Foundation | ||
My rating (0-5) | 3 |
My notes: When I first discovered Haxe years ago I thought to have found the perfect programming language. I've tested Haxe many times during the years since then. Unfortunately I had to stop everytime for the same reason: the strengh of Haxe is exactly to be able to be transpiled to many target languages, but this is also its worst weakness: being just a transpiled language you always miss the typical functionalities a native language usually has: easy code completion and all the rest. With any language you are a first order citizen at least on one platform, with Haxe you are never ever a first order citizen and this greatly reduces your productivity. Unfortunately Haxe is a wonderful dream that cannot come true. 😢
Java
Features | Targets | ||
---|---|---|---|
Type system | static | JVM | yes |
Type inference | yes | CLR | no¹ |
Automatic memory | yes | JavaScript | no² |
Assertions | yes | WebAssembly | no² |
Object oriented | yes | Windows | yes |
Multiple inheritance | no | Linux | yes |
Prototype extensions | no | MacOS | yes |
Instance extensions | no | Android | yes |
Generics | yes | iOS | no³ |
Annotations | yes | ||
Union types | no | ||
Intersection types | no | ||
Alias of types | no | ||
Functional | no | ||
Higher-order fn | no | ||
Exception handling | yes | ||
Operator overloading | no | ||
Custom get/set | no | ||
Multithreading | yes | ||
Coroutines | no | ||
Closures | no | ||
Multiple returns | no | ||
String templates | no | ||
Multi-line strings | no | ||
Collections | no | ||
Preprocessor | no | ||
License | depends on the implementation | ||
Inventor(s) | James Gosling | ||
My rating (0-5) | 4 |
My notes: As you can see from the table Java misses a lot of the modern things one expects to find in a programming language. Despite this for me this is the only language, togheter with JavaScript, that deserves a 4. This mostly depends on the fact that these two languages are the best, even if not perfect at all, for multiplatform development.
1. There is at least IKVM.NET with which it seems possibile to run Java on CLR. I've never tryed it.
2. There is no official way to run Java in a JavaScript environment, but some transpilers Java/JavaScript exist (GWT, CheerpJ, TeaVM, JSweet, j2cl, etc.). I've tried almost all of them. For me the only really viable one is JSweet, still with a lot of headache.
3. There are some AOT compilers that give the opportunity to develop and run a Java application on iOS. Honestly I've tried many of them during the years but I don't remember of a solution so robust to be confident to list here.
JavaScript
Features | Targets | ||
---|---|---|---|
Type system | dynamic | JVM | no¹ |
Type inference | not applicable | CLR | no¹ |
Automatic memory | yes | JavaScript | yes |
Assertions | no | WebAssembly | no¹ |
Object oriented | yes | Windows | no¹ |
Multiple inheritance | no | Linux | no¹ |
Prototype extensions | yes | MacOS | no¹ |
Instance extensions | yes | Android | no¹ |
Generics | not applicable | iOS | no¹ |
Annotations | no | ||
Union types | not applicable | ||
Intersection types | not applicable | ||
Alias of types | not applicable | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | no | ||
Custom get/set | yes | ||
Multithreading | no | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | no | ||
String templates | yes | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | no | ||
License | depends on the implementation | ||
Inventor(s) | Brendan Eich | ||
My rating (0-5) | 4 |
My notes: I would never use JavaScript to program, as I've explained very well so far. But for scripting and as a target of a more enhanced language with which make serious programming, well nothing is better than it.
1. JavaScript can be run pratically everywhere or inside a browser (on every OS) or with node.js (on every OS, even iOS) or implemented via third party engines for the JVM and even for CLR. I write 'no' here in the sense that it's not a language you can compile to native executables.
Kotlin
Features | Targets | ||
---|---|---|---|
Type system | static | JVM | yes |
Type inference | yes | CLR | no |
Automatic memory | yes | JavaScript | yes |
Assertions | yes | WebAssembly | yes |
Object oriented | yes | Windows | yes |
Multiple inheritance | no | Linux | yes |
Prototype extensions | yes | MacOS | yes |
Instance extensions | no | Android | yes |
Generics | yes | iOS | yes |
Annotations | yes | ||
Union types | no | ||
Intersection types | no | ||
Alias of types | yes | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | yes | ||
Custom get/set | yes | ||
Multithreading | no | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | no | ||
String templates | yes | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | no | ||
License | Apache License 2.0 | ||
Inventor(s) | JetBrains | ||
My rating (0-5) | 0 |
My notes: I don't like Kotlin. I don't like it at all. For the sake of clarity I specify immediately that I'm an absolute huge fan of JetBrains' IDEs, so my not liking Kotlin has nothing to do with the company which invented it. On the contrary, exactly because Kotlin has been born by jetBrains I gave it way more chances to conquer my liking than I would have made if it was not by JetBrains. Another point I also want to highlight is that Kotlin has almost 100% of what I look for in a programming language, which also contributes to explain why I tried so hard to force myself to like Kotlin. So why I dislike it so much, at a point to give it a resounding 0, the worst rating of this whole list of programming langauges? Well, it's because I think Kotlin has almost all I need but 100% of it is made in the worst and most horrible way one could conceive. I'm not here to write details about what and why I don't like about Kotlin, it would take the writing of a book, it's enough to say that every single construct misses even the smallest hint of elegance, when it's not entirely a mess without any bit of coherence or at least effectiveness. Just two examples to give a concrete idea of what I mean. First: constructors are almost impossibile to grasp, they are a total mess, even if you learn them you can never get confortable with them. Second: I'm totally against the recent wars to nulls; the so called null safety madness Kotlin embraces with a so hysterical and obsessive ardor renders 10 times worse the problems it try to solve to begin with. And the same is for all the other features of the language. Not only. Another thing I cannot understand is why oh why they had to postpone the types instead of leaving them where they are in Java?
I can understand that TypeScript makes this (and still I don't like it), but why should do it a language whose self declared first goal is to propose itself as a replacement for Java?
In what way
is shorter and easier than the usual:
or the new Java way:
I swear, I would be really happy if one of the Kotlin designers would explain me at least this.
JetBrains you are so incredibly careful, precise and elegant with your IDEs, why not the same attention with your language?
Nim
Features | Targets | ||
---|---|---|---|
Type system | static | JVM | no |
Type inference | yes | CLR | no |
Automatic memory | automatic or manual | JavaScript | yes |
Assertions | yes | WebAssembly | no¹ |
Object oriented | yes | Windows | yes |
Multiple inheritance | no | Linux | yes |
Prototype extensions | no | MacOS | yes |
Instance extensions | no | Android | yes |
Generics | yes | iOS | yes |
Annotations | no | ||
Union types | no | ||
Intersection types | no | ||
Alias of types | yes | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | yes | ||
Custom get/set | yes | ||
Multithreading | yes | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | no | ||
String templates | no | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | yes | ||
License | MIT | ||
Inventor(s) | Andreas Rumpf | ||
My rating (0-5) | 3 |
My notes: In an ideal world Nim would have supplanted Python years ago. This is a very good language. It just happens that I'm for curly-bracket languages, otherwise Nim would probably be one of my favourite programming languages.
1. Nim also compile to C/C++ and a toolchain to get C/C++ compiled for WebAssembly is absolutely existent and very stable, so teoretically nothing should prevent to compile Nim to WebAssembly too.
PHP
Features | Targets | ||
---|---|---|---|
Type system | dynamic | JVM | no |
Type inference | not applicable | CLR | no |
Automatic memory | yes | JavaScript | no¹ |
Assertions | yes | WebAssembly | no |
Object oriented | yes | Windows | yes |
Multiple inheritance | no | Linux | yes |
Prototype extensions | no | MacOS | yes |
Instance extensions | yes | Android | no |
Generics | not applicable | iOS | no |
Annotations | yes | ||
Union types | not applicable | ||
Intersection types | not applicable | ||
Alias of types | not applicable | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | yes | ||
Custom get/set | yes | ||
Multithreading | yes | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | no | ||
String templates | yes | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | no | ||
License | PHP License | ||
Inventor(s) | Rasmus Lerdorf | ||
My rating (0-5) | 1 |
My notes: A famous joke goes that one day a boy meets a friend and tells him that he received a job offer as a PHP programmer from PornHub. The friend asks back if he accepted and the first sadly replies: "Honestly no, I didn't have the courage to tell my parents that I would work with PHP!". Of course it's just a joke. Modern PHP nowaday is just an average bad programming language like many others.
Python
Features | Targets | ||
---|---|---|---|
Type system | dynamic | JVM | no¹ |
Type inference | not applicable | CLR | no² |
Automatic memory | yes | JavaScript | no³ |
Assertions | yes | WebAssembly | no⁴ |
Object oriented | yes | Windows | yes |
Multiple inheritance | yes | Linux | yes |
Prototype extensions | yes | MacOS | yes |
Instance extensions | yes | Android | yes |
Generics | not applicable | iOS | yes |
Annotations | no | ||
Union types | not applicable | ||
Intersection types | not applicable | ||
Alias of types | not applicable | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | yes | ||
Custom get/set | yes | ||
Multithreading | yes | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | yes | ||
String templates | no | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | yes | ||
License | BSD-style license GPL compatible | ||
Inventor(s) | Guido van Rossum | ||
My rating (0-5) | 1 |
My notes: People around the world are mad about Python. I'm mad about why they are. I will say it here and nowhere ever more: I think Python is the best programming language for people who need/want to program and still their primary job has nothing to do with programming. Sorry, but for me this is really an awful programming language. I use it often so I know what I'm saying. I'm forced to use it because I make a lot of AI programming and as I just said AI people use Python to program exactly because they are AI people and not programmers. Still when I program in Python I feel all the self
I have to write in my hands and all those spaces, spaces, spaces... 😠, now if Python could just disappear from planet Earth... that would be a thing! 😜😜😜 Unfortunately, as you can see, people are porting python everywhere, it will surely conquere the world! 😭
1. Still have a look at Jython.
2. But have a look at ironPython.
3. Despite this pay a trip to Transcrypt.
4. Still throw an eye on Pyodide.
Ruby
Features | Targets | ||
---|---|---|---|
Type system | dynamic | JVM | ?¹ |
Type inference | not applicable | CLR | no |
Automatic memory | yes | JavaScript | ?² |
Assertions | yes | WebAssembly | no |
Object oriented | yes | Windows | yes |
Multiple inheritance | no | Linux | yes |
Prototype extensions | yes | MacOS | yes |
Instance extensions | yes | Android | no |
Generics | not applicable | iOS | no |
Annotations | no | ||
Union types | not applicable | ||
Intersection types | not applicable | ||
Alias of types | not applicable | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | yes | ||
Custom get/set | yes | ||
Multithreading | long story... | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | no | ||
String templates | yes | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | no | ||
License | Ruby License, GPLv2, or 2-clause BSD | ||
Inventor(s) | Yukihiro Matsumoto | ||
My rating (0-5) | 1 |
My notes: I don't believe in dynamic type system languages, which Ruby is. I like C-like syntaxes, which Ruby has not. I'm very serious about the ratio performance/advantages of a programming language and Ruby clearly plays bad on this. What other? Nothing, just that Ruby for me is not a gem at all, sorry.
1. There is JRuby that runs Ruby applications on the JVM. I have no direct exeperience but browsing on reddit and the like I see mixed feelings, from people enthusiastic about its performances and compatibility to those who talk about continuous problems and headaches. There is also TruffleRuby, a Java implementation using the Truffle language implementation framework with GraalVM.
2. Opal promises to transpile Ruby to JavaScript.
Rust
Features | Targets | ||
---|---|---|---|
Type system | static | JVM | no¹ |
Type inference | yes | CLR | no |
Automatic memory | no | JavaScript | yes |
Assertions | yes | WebAssembly | yes |
Object oriented | ambiguous | Windows | yes |
Multiple inheritance | no | Linux | yes |
Prototype extensions | no | MacOS | yes |
Instance extensions | no | Android | yes |
Generics | yes | iOS | yes |
Annotations | yes | ||
Union types | partial | ||
Intersection types | no | ||
Alias of types | yes | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | no | ||
Operator overloading | yes | ||
Custom get/set | no | ||
Multithreading | yes | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | no | ||
String templates | no | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | no | ||
License | MIT or Apache 2.0 | ||
Inventor(s) | Graydon Hoare | ||
My rating (0-5) | 2 |
My notes: I know they say that Rust has been the "most loved programming language" in the Stack Overflow Developer Survey every year since 2016. I myself have studied Rust many times and promised to myself to try it in a real project as soon as possibile. Still I've never tried it. Not having tried it I cannot say any bad thing of it if not maybe just one: why such a potentially good languqage has never been able to convince me to give it a chance? Well I think it all depends on the way Rust forces you to manage memory. I find very intriguing and ingenious all the ownership, referencing and borroving mechanism they've invented with Rust, and surely I understand that this implies a lot of runtime and performance benefits. However, I also think it's really too complex and low level. When to implement a bi-directional linked list a language forces you to hours and hours of almost impossibile thinking just to admit in the end that the only way to do it is to borrow the solution from a language pattern book... well honestly I don't think this language is serving my needs very well.
Scala
Features | Targets | ||
---|---|---|---|
Type system | static | JVM | yes |
Type inference | yes | CLR | no |
Automatic memory | yes | JavaScript | yes |
Assertions | yes | WebAssembly | no |
Object oriented | yes | Windows | no¹ |
Multiple inheritance | no | Linux | no¹ |
Prototype extensions | yes | MacOS | no¹ |
Instance extensions | no | Android | no¹ |
Generics | yes | iOS | no¹ |
Annotations | yes | ||
Union types | no | ||
Intersection types | yes | ||
Alias of types | yes | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | yes | ||
Custom get/set | yes | ||
Multithreading | yes | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | yes | ||
String templates | yes | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | no | ||
License | Apache License 2.0 | ||
Inventor(s) | Martin Odersky | ||
My rating (0-5) | 3 |
My notes: Scala is a very good programming language offering real improvements over Java. Unfortunately also Scala inventor felt the urgency to change the syntax from Java so much that in fact you really need to learn a completely different language to get those few improvements Scala offers. Is it worth the effort? Not for me.
1. Being compiled to JVM bitcode, Scala programs can be compiled to native executable with GraalVM. There is also *Scala Native* which is a Scala compiler that targets the LLVM compiler infrastructure to create executable code that uses a lightweight managed runtime.
Swift
Features | Targets | ||
---|---|---|---|
Type system | static | JVM | no |
Type inference | yes | CLR | no |
Automatic memory | almost | JavaScript | no |
Assertions | yes | WebAssembly | no |
Object oriented | yes | Windows | no¹ |
Multiple inheritance | no | Linux | yes² |
Prototype extensions | yes | MacOS | yes |
Instance extensions | yes/no | Android | no |
Generics | yes | iOS | yes |
Annotations | yes | ||
Union types | no | ||
Intersection types | no | ||
Alias of types | yes | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | yes | ||
Custom get/set | yes | ||
Multithreading | yes | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | yes | ||
String templates | no | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | yes | ||
License | Apache License 2.0 | ||
Inventor(s) | many + Apple Inc. | ||
My rating (0-5) | 1 |
My notes: I've programmed in Objective-C for macOs and iOS many times, and I'm absolutely sure that I've never ever seen a programming language so horrible, at least from a syntax point of view but to be honest not only, as Objective-C. So welcome Swift because it's for sure that I'm not the only one to deeply hate Objective-C. Having said that, for the rest, I think Swing brings nothing on the table of the programming world. All yet seen and re-seen many times. Yet been there 20 years before. Congrats Apple for alleviating a little bit your programmers pains.
TypeScript
Features | Targets | ||
---|---|---|---|
Type system | static (optional) | JVM | no |
Type inference | yes | CLR | no |
Automatic memory | yes | JavaScript | yes |
Assertions | yes | WebAssembly | no |
Object oriented | yes | Windows | no |
Multiple inheritance | no | Linux | no |
Prototype extensions | yes | MacOS | no |
Instance extensions | yes | Android | no |
Generics | yes | iOS | no |
Annotations | yes | ||
Union types | yes | ||
Intersection types | yes | ||
Alias of types | yes | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | no | ||
Custom get/set | yes | ||
Multithreading | no | ||
Coroutines | yes | ||
Closures | yes | ||
Multiple returns | no | ||
String templates | yes | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | no | ||
License | Apache License 2.0 | ||
Inventor(s) | Microsoft | ||
My rating (0-5) | 3 |
My notes: I see TypeScript as the web hero, the language who is saving the whole web echosystem from the JavaScript dynamic type system madness. We all owe a lot to this language and to the type definition files used nowaday by every statically typed programming language transpiled to JavaScript (Dart, Kotlin, Java, of course TypeScript itself, etc.). Maybe one day most of client side programming will be made on WebAssembly and everyone will be free to choose the programming language of her choice, but for sure untile that day TypeScript, please, stay with us.
Xtend
Features | Targets | ||
---|---|---|---|
Type system | static | JVM | yes |
Type inference | yes | CLR | no |
Automatic memory | yes | JavaScript | no |
Assertions | no | WebAssembly | no |
Object oriented | yes | Windows | no¹ |
Multiple inheritance | no | Linux | no¹ |
Prototype extensions | yes | MacOS | no¹ |
Instance extensions | no | Android | yes |
Generics | yes | iOS | no¹ |
Annotations | yes | ||
Union types | no | ||
Intersection types | no | ||
Alias of types | no | ||
Functional | yes | ||
Higher-order fn | yes | ||
Exception handling | yes | ||
Operator overloading | yes | ||
Custom get/set | yes | ||
Multithreading | yes | ||
Coroutines | no | ||
Closures | yes | ||
Multiple returns | no | ||
String templates | yes | ||
Multi-line strings | yes | ||
Collections | yes | ||
Preprocessor | no | ||
License | Eclipse Public License | ||
Inventor(s) | Sven Efftinge, Sebastian Zarnekow | ||
My rating (0-5) | 2 |
My notes: Yes, yet another Java better than Java, which as usual changes the syntax at least as much as it takes to keep away those who like Java syntax.
1. As usual, being a JVM language could be compiled to native with GraalVM.
Conclusion
I started this analysis for a specific needing I had, it ended out providing me way more insights than I was ever hoping for. The most intriguing one is that while I would strongly like to find and use a programming language that has all 28 features I chose, I have to admit that the only two languages, Java and JavaScript, that reached the best rating I've given here, which is not even the maximun possible, just a 4 out of 5, are also the ones that have less of the 28 features. I'm still trying to explain this to myself.
Another takeaway of the study is the overall feeling that it left to me: it really seems to me that we humans are just at the beginning of the software programming adventure. Seeing how many years it's taking for us to even just enhance a little bit garbage collection or OOP in itself, or even very small improvements like entering multi line strings... is at the same time moving but also a little bit discouraging.
While it has been fun to remember how all this matters changed and evolved during my decades of software programming, it has also been worrysome noiticing that all this stuff is always the same, repeated again and again with minimal variations at the point to leave me the feeling that progress is really moving too slow in this field.
In the end what I was looking for was something I was almost sure I would find. I just needed a programming language that offered all 28 features I selected and was able to produce targets at least for the JVM and WebAssembly, or alternatively for WebAssembly and native for the 5 OSes.
Was I looking for too much? Well, turns out that yes, because no such language already exist. What to say? Mhhh, well, maybe it's just time to roll up the sleeves and build it myself.
Thanks for reading.
If you like, share your comments on reddit.