Why there are so many programming languages
Published on 2026-09-12 by frfrand
Cada uno optimiza algo distinto y lo paga en otro lado. Compilado o interpretado, tipado o no, con recolector de basura o sin él: los tres ejes que explican casi todas las diferencias.

There are thousands of programming languages. The reasonable question is why, if they all end up making a processor execute instructions.
The answer is that each one optimizes something different, and pays for it elsewhere. Almost all differences are explained by three axes.
Axis 1: when the code is translated
Compiled. It is translated into machine code before execution. C, Rust, Go.
You gain execution speed and early error detection: the compiler rejects the program before it reaches a user. You lose immediacy, because between changing something and seeing it there is a compilation step.
Interpreted. It is translated while it runs. Python, JavaScript, Ruby.
You gain development speed: you change and see. You lose performance and early detection; many errors only appear when that line is executed.
In between. Java and C# compile to an intermediate format that a virtual machine translates into native code while it runs. This allows optimizations that a static compiler cannot make, because it knows the real behavior of the program.
Axis 2: when types are verified
Static typing. Types are checked at compile time. If you pass a text where a number is expected, it does not compile.
Dynamic typing. They are checked at execution time. More flexible, and the error appears in production.
The debate over which is better has been going on for decades, and the practical synthesis is quite clear: in small, short-lived projects, dynamic typing is faster; in large, long-lived projects, static typing saves much more than it costs.
This explains a trend of recent years: TypeScript over JavaScript, type annotations in Python. Start flexible and add verification when the project grows.
Axis 3: who frees memory
This axis is the one that produces the most profound differences.
You. In C, you reserve and free manually. Total control, and a category of errors (using freed memory, buffer overflow) that caused a huge part of the vulnerabilities of the last decades.
A garbage collector. Java, Go, Python, JavaScript. An automatic process frees what is no longer used. You eliminate that class of errors, in exchange for unpredictable pauses and higher memory consumption.
The compiler proves it. This is Rust's contribution: an ownership and borrowing system that allows the compiler to verify at compile time that memory is freed correctly. No garbage collector, no pauses, and a considerable learning curve.
Why new ones keep appearing
Every new language is born from a concrete dissatisfaction:
- Go was born at Google due to compilation times and the complexity of C++, betting on a deliberately simple language with good concurrency.
- Rust was born at Mozilla due to memory errors in browsers.
- TypeScript was born because JavaScript grew beyond what its lack of types could sustain.
- Swift and Kotlin were born to replace old languages on platforms where there was no alternative.
None "replaced" the previous one. They were added, because each one solved a different case well.
How to choose, honestly
In practice, the language rarely decides the success of a project. Four criteria matter more than the elegance of the syntax:
What the ecosystem has. Available libraries save more time than any language feature.
What the team knows. A team that masters a tool beats a better tool that no one knows.
What real restrictions exist. Real-time, very limited memory, a platform that imposes the choice.
How it will be maintained. In two years, with other people reading that code.

