Interactive field guide
The Grand Programming Languages Spectrum
October 12, 2026 · programming languages, dataEvery few months someone publishes a ranking of programming languages, and every ranking tells a different story. TIOBE says C is the second most popular language in the world. GitHub says TypeScript is first. Stack Overflow’s survey says JavaScript, as it has for over a decade. They are all right, because they measure different things: search results, contributors, survey answers.
This is an attempt at the whole picture. It covers twenty-seven languages: the most widely used general-purpose languages across seven published rankings, plus the smaller ones developers admire out of all proportion to their size. Each is scored on eleven facets, from performance and safety to tooling and job demand, and you can lay them out along any of them. The facet scores are my judgement, informed by benchmarks and studies; the popularity data comes from the sources. Every language also has a full profile, with the same small program written in each, so you can see the differences rather than read about them.
01 · The lineup
Twenty-seven languages, six families
Families group languages by the deal they offer: who manages memory, how much the compiler checks, and where the code runs. Within each family, languages are in order of birth. Hover over a tile for a summary, or select it for the full profile.
02 · The spectrum
Line them up along any facet
Pick a lens and all twenty-seven languages slide into place, from one end of the spectrum to the other. Within a stack, the more popular language sits closer to the axis.
How fast and lean is typical, idiomatic code?
Five languages share the top: C, C++, Rust, Zig and Odin compile ahead of time and have no garbage collector. The big cluster at 7–8 is the managed mainstream, within a small factor of C for most server work. The real story is the gap to the bottom. In Pereira et al.’s benchmark study, Python and Ruby took 60 to 70 times as long as C. That is why their fast libraries are written in C, C++ or Rust.
03 · The trade-off map
Every language is a trade-off
One axis hides as much as it shows. Put two facets against each other and the trade-offs appear. Start with one of the questions below, or choose your own axes. Where tiles had to move apart to stay readable, a thin line points back to their exact position.
For decades you had to pick one. The top-right corner is now well populated: Go, Java, C#, Kotlin and Swift are fast enough for almost anything and approachable enough for most teams. Rust and Zig buy the last stretch of speed with a steeper climb. Python trades speed for approachability, then wins much of it back through libraries written in C.
04 · Popularity
Seven rankings, one consensus
No single source can tell you how popular a language is. TIOBE and PYPL count web searches, RedMonk compares GitHub with Stack Overflow, IEEE Spectrum blends seven signals, GitHub counts contributors, and JetBrains and Stack Overflow survey developers. Each line follows one language across all seven, ending at its average position. Hover over a line, or pick one of the stories.
Show the published ranks as a table
| Language | TIOBEOct 2026 | PYPLOct 2026 | RedMonkJan 2026 | IEEE2025 | GitHub2025 | JetBrains2025 | Stack Overflow2026 | Consensus |
|---|---|---|---|---|---|---|---|---|
| Python | #1 | #1 | #2 | #1 | #2 | #2 | #4 | #1 |
| Java | #4 | #2 | #3 | #2 | #4 | #3 | #7 | #2 |
| JavaScript | #6 | #6 | #1 | #6 | #3 | #1 | #1 | #3 |
| C++ | #3 | #3 | #7 | #3 | #8 | #7 | #10 | #4 |
| C# | #5 | #11 | #4 | #5 | #5 | #8 | #8 | #5 |
| TypeScript | #38 | #12 | #6 | #7 | #1 | #5 | #6 | #6 |
| C | #2 | #3 | #10 | #8 | — | #10 | #11 | #7 |
| PHP | #12 | #7 | #4 | #12 | #6 | #12 | #13 | #8 |
| Go | #11 | #17 | #12 | #10 | #10 | #9 | #14 | #9 |
| Rust | #10 | #8 | #20 | #14 | — | #13 | #12 | #10 |
| Swift | #14 | #10 | #11 | #16 | — | #14 | #18 | #11 |
| R | #8 | #4 | #13 | #11 | — | — | #21 | #12 |
| Kotlin | #32 | #19 | #14 | #13 | — | #10 | #15 | #13 |
| Ruby | #28 | #14 | #9 | #17 | — | #16 | #19 | #14 |
| Dart | #27 | #18 | #18 | #15 | — | #14 | #20 | #15 |
| Lua | #35 | #20 | — | #21 | — | #16 | #16 | #16 |
| Scala | #40 | #22 | #14 | #28 | — | #16 | #35 | #17 |
| Julia | #18 | #21 | — | #31 | — | — | #39 | #18 |
| Zig | #46 | #24 | #82 | — | — | — | #29 | #19 |
| Haskell | #41 | #27 | — | #30 | — | — | #34 | #20 |
| OCaml | #26 | — | — | #40 | — | — | #44 | #21 |
| Elixir | 51–100 | — | — | #43 | — | — | #32 | #22 |
| Erlang | 51–100 | — | — | #52 | — | — | #38 | #23 |
| Clojure | 51–100 | — | — | #51 | — | — | #40 | #24 |
| F# | 51–100 | — | — | — | — | — | #43 | #25 |
| Gleam | — | — | — | — | — | — | #41 | #26 |
| Odin | — | — | — | — | — | — | #49 | #27 |
Ranks as published. PYPL ranks C and C++ together. TIOBE publishes positions 51 to 100 only as a band. GitHub publishes its top ten, and RedMonk its top twenty plus a few named positions.
05 · Family tree
Nothing is invented from scratch
Every language on this list borrowed its best ideas. The faded nodes are ancestors that didn’t make the lineup but shaped it: Lisp, ML, Smalltalk, Prolog. Hover over or focus any node to trace what it took and what it passed on.
Follow a language’s line to see where its ideas came from.
06 · Head to head
Pick two or three and compare
Choose a classic matchup or build your own. The dots show each language on every facet, the list picks out where they differ most, and at the bottom you’ll find the same program written in each.
Where they differ most
The same program in each
Total the paid orders per customer, then print customers from the highest total to the lowest.
07 · Choosing one
Which language fits your project?
Start from a kind of project, then adjust what matters to you. The fit is a weighted average of the facet scores, reduced when the language is rarely used for that kind of work. It won’t know your team, so treat it as a shortlist, not a verdict.
Best fits
08 · My take
My take on the spectrum
Language choice depends on the trade-offs
Rust asks you to learn ownership and borrowing for memory safety without a garbage collector. Go accepts a collector to keep memory management simple. I see languages such as Go, Kotlin, Swift and Rust as different answers to the compromises their predecessors made. Older languages are changing too: today’s Java and C# look little like their 2010 selves.
The managed middle runs business software
Java, C#, Go and Kotlin share a profile: statically typed, garbage collected, fast enough, with mature tools and long compatibility records. They score high across many facets, a combination that suits long-lived enterprise software. Boring is a feature when a system has to outlive its authors. C# was TIOBE’s language of the year for 2025, and Java and C# both make the top six of IEEE Spectrum’s jobs ranking.
Types are winning, even in dynamic languages
In August 2025 TypeScript became the most used language on GitHub by monthly contributors, up 66% in a year to 2.6 million, and it tops JetBrains’ Language Promise Index. The dynamic languages are moving the same way. Python has type hints and fast checkers, PHP enforces type declarations, Ruby has RBS and Sorbet, and Elixir 1.20 now type-checks every program without annotations. No major language has gone the other way. AI is accelerating the shift: GitHub credits typed languages for making AI-assisted code more reliable, and a 2025 study found that 94% of compilation errors in LLM-generated TypeScript were type errors. The type checker is what catches the model’s mistakes.
Memory safety moved from preference to policy
Microsoft and Google’s Chromium team both found that around 70% of their serious security vulnerabilities come from memory-safety bugs. In 2024 the White House urged software makers to adopt memory-safe languages, and CISA and the FBI asked them to publish memory-safety roadmaps by the end of 2025. The data backs the policy: as Android shifted new code to Rust, memory-safety bugs fell from 76% of its vulnerabilities in 2019 to below 20% in 2025. C and C++ aren’t going anywhere, and C++26 adds a hardened standard library, but new C or C++ in security-sensitive code now needs a reason.
Runtimes matter more than syntax
The JVM hosts Java, Kotlin, Scala and Clojure. .NET hosts C# and F#. The BEAM hosts Elixir and Gleam. JavaScript engines run JavaScript, TypeScript, and code compiled from Kotlin, Dart, F#, Gleam and ClojureScript. A language on an established runtime inherits its libraries, garbage collector, concurrency model and deployment story on day one. That is how Kotlin went from announcement to Android’s preferred language in eight years, and why Gleam was usable in production at 1.0: it could call decades of Erlang libraries. Choose the runtime first and the language second.
Admiration is a selection effect
The most admired languages are small: Odin at 82%, Elixir at 62% and Zig at 58% of users wanting to keep using them, against 39% for Java and 42% for JavaScript. Part of that is who answers. People who write Elixir went looking for it, while many people write Java because their employer does. Bjarne Stroustrup put it best: there are only two kinds of languages, the ones people complain about and the ones nobody uses. The impressive results are the exceptions: TypeScript and Python stay well liked at scale, and Rust is admired by 67% of its users even with 18% of developers using it.
Popularity depends on who you ask
TIOBE has C at number two and TypeScript at 38; GitHub has TypeScript first and C outside its top ten. JetBrains’ survey puts Kotlin at 18% usage, which says as much about JetBrains’ audience as about Kotlin. Every index measures a population, not the world, which is why the consensus here averages seven of them. The rankers are also warning that AI is eroding their inputs: fewer searches and Stack Overflow questions as developers ask assistants instead. Expect the next few years of rankings to be noisier.
Concurrency is the new dividing line
Two decades ago the big argument was objects against functions. Now it is how a language handles ten thousand things at once. Languages designed for multicore machines, such as Go, Rust, Elixir and Gleam, have it built in. Older ones are retrofitting at great effort: Java’s virtual threads, Python’s free-threaded build, Ruby’s Ractors, Swift 6’s data-race checks. async/await, which C# brought to the mainstream in 2012, has since spread to JavaScript, Python, Rust, Swift and Dart, bringing the “function colouring” problem with it.
AI makes the rich richer, and rewards strictness
Language models write better code in popular languages, because that is what they were trained on. Research on multilingual code benchmarks found performance correlates with popularity, and that models struggle with low-resource languages such as Julia, Lua, OCaml and R. That is a headwind for every new language, which already faces a cold start. But AI also rewards languages whose compilers catch mistakes: types, exhaustive matching, borrow checking. My bet is that the languages that gain most from AI are the ones that are both popular and strict: TypeScript, C#, Kotlin, Go and Rust.
Learn a portfolio, not a favourite
Ideas move between families, as the family tree shows: pattern matching from ML to Rust, Swift and C#, async from F# to C# to everyone. Developers who know one language from several families can see these ideas coming. A practical portfolio: one systems language (Rust or C), one managed workhorse (Java, C#, Go or Kotlin), TypeScript for the web, Python for data and glue, and one functional language (Elixir, F#, Clojure or Haskell). The last one will change how you write the other four.
09 · The matrix
Everything in one table
The reference view. Sort by any column, switch to traits for the technical details, or select a language for its profile.
| Python | #1 | 50.6% | 3 | 4 | 10 | 8 | 4 | 10 | 7 | 7 | 7 | 10 | 9 | 1991 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Java | #2 | 38.5% | 8 | 6 | 7 | 6 | 8 | 10 | 9 | 8 | 10 | 10 | 5 | 1995 |
| JavaScript | #3 | 42.0% | 6 | 3 | 8 | 7 | 5 | 10 | 6 | 10 | 9 | 10 | 3 | 1995 |
| C++ | #4 | 45.8% | 10 | 2 | 2 | 7 | 6 | 9 | 4 | 9 | 9 | 8 | 5 | 1985 |
| C# | #5 | 50.0% | 8 | 7 | 7 | 8 | 8 | 9 | 9 | 8 | 9 | 9 | 5 | 2000 |
| TypeScript | #6 | 53.0% | 6 | 6 | 7 | 8 | 5 | 10 | 8 | 9 | 7 | 9 | 10 | 2012 |
| C | #7 | 45.9% | 10 | 1 | 5 | 2 | 4 | 9 | 4 | 10 | 10 | 6 | 4 | 1972 |
| PHP | #8 | 35.7% | 4 | 4 | 8 | 5 | 2 | 8 | 7 | 3 | 7 | 7 | 3 | 1995 |
| Go | #9 | 49.5% | 8 | 6 | 9 | 4 | 9 | 8 | 10 | 6 | 10 | 7 | 7 | 2009 |
| Rust | #10 | 67.4% | 10 | 10 | 3 | 8 | 9 | 7 | 10 | 9 | 9 | 5 | 9 | 2012 |
| Swift | #11 | 48.5% | 8 | 9 | 7 | 8 | 7 | 6 | 7 | 5 | 6 | 6 | 5 | 2014 |
| R | #12 | 40.7% | 2 | 3 | 6 | 7 | 2 | 7 | 7 | 3 | 8 | 4 | 4 | 1993 |
| Kotlin | #13 | 43.1% | 8 | 8 | 7 | 8 | 8 | 9 | 8 | 8 | 8 | 6 | 6 | 2011 |
| Ruby | #14 | 42.4% | 3 | 3 | 8 | 9 | 3 | 7 | 7 | 4 | 7 | 5 | 2 | 1995 |
| Dart | #15 | 42.3% | 7 | 8 | 8 | 6 | 5 | 6 | 9 | 7 | 6 | 3 | 6 | 2011 |
| Lua | #16 | 40.8% | 3 | 3 | 9 | 5 | 3 | 4 | 4 | 7 | 6 | 2 | 6 | 1993 |
| Scala | #17 | 39.2% | 7 | 8 | 4 | 10 | 8 | 8 | 6 | 6 | 5 | 4 | 2 | 2004 |
| Julia | #18 | 47.4% | 8 | 5 | 7 | 9 | 7 | 5 | 7 | 3 | 8 | 2 | 5 | 2012 |
| Zig | #19 | 58.3% | 10 | 4 | 5 | 5 | 5 | 4 | 7 | 8 | 2 | 1 | 8 | 2016 |
| Haskell | #20 | 47.8% | 7 | 9 | 2 | 10 | 8 | 5 | 5 | 4 | 6 | 2 | 3 | 1990 |
| OCaml | #21 | 51.5% | 8 | 8 | 5 | 9 | 7 | 5 | 7 | 6 | 8 | 3 | 5 | 1996 |
| Elixir | #22 | 62.1% | 4 | 6 | 6 | 8 | 10 | 6 | 8 | 5 | 9 | 3 | 6 | 2012 |
| Erlang | #23 | 49.1% | 4 | 6 | 5 | 6 | 10 | 6 | 7 | 4 | 10 | 3 | 3 | 1986 |
| Clojure | #24 | 48.7% | 6 | 5 | 5 | 9 | 8 | 7 | 6 | 6 | 10 | 2 | 3 | 2007 |
| F# | #25 | 48.3% | 7 | 8 | 6 | 9 | 7 | 7 | 7 | 6 | 8 | 2 | 3 | 2005 |
| Gleam | #26 | 52.3% | 4 | 9 | 7 | 6 | 9 | 4 | 9 | 5 | 6 | 1 | 8 | 2016 |
| Odin | #27 | 82.4% | 10 | 4 | 7 | 5 | 4 | 3 | 6 | 7 | 3 | 1 | 7 | 2016 |
| Language | Typing | Memory | Runs as | Concurrency | Null handling | Packages |
|---|---|---|---|---|---|---|
| Python | Gradual Dynamic, strong; optional type hints checked by external tools | Garbage collected Reference counting plus a cycle-detecting collector | Interpreter CPython bytecode interpreter; experimental JIT since 3.13 | asyncio, threads (GIL, or the opt-in free-threaded build), processes | None, caught only by type checkers | pip, uv, Poetry · PyPI |
| Java | Static Static, strong, nominal; local inference with var | Garbage collected Garbage collected (G1, ZGC, and others) | Managed runtime JVM bytecode, JIT-compiled; GraalVM native images | Platform threads, virtual threads (Java 21+), java.util.concurrent | null everywhere; Optional<T> by convention | Maven, Gradle · Maven Central |
| JavaScript | Dynamic Dynamic, weak (implicit coercion) | Garbage collected Garbage collected | Managed runtime JIT-compiled by the engine (V8, SpiderMonkey, JavaScriptCore) | Single-threaded event loop, promises, async/await; workers | Both null and undefined | npm, pnpm, Yarn, Bun · npm registry |
| C++ | Static Static, mostly strong; templates | Manual Manual, with RAII and smart pointers | Native code Compiled to native code | Threads, atomics, futures, C++20 coroutines | nullptr, unchecked; std::optional available | None official; vcpkg, Conan, with CMake for builds |
| C# | Static Static, strong, inferred locals; reified generics | Garbage collected Garbage collected; value types and Span<T> for control | Managed runtime .NET runtime, JIT-compiled; Native AOT available | async/await (C# popularised it), tasks, channels | Nullable reference types, flagged by compiler warnings | dotnet CLI · NuGet |
| TypeScript | Static Static, structural, inferred; deliberately unsound | Garbage collected Garbage collected (runs as JavaScript) | Managed runtime Compiled to JavaScript, types erased; compiler rewritten in Go for 7.0 | Same as JavaScript: event loop, promises, workers | Strict null checks make null and undefined explicit | npm and friends · npm registry |
| C | Static Static, weak; implicit conversions | Manual Manual: malloc and free | Native code Compiled to native code | OS threads and atomics (pthreads, C11 threads) | NULL pointers, unchecked | None official; system packages, vcpkg, Conan |
| PHP | Gradual Dynamic, with type declarations enforced at runtime | Garbage collected Reference counting with a cycle collector, reset per request | Interpreter Zend Engine bytecode with OPcache and an optional JIT | Shared-nothing request processes; Fibers since 8.1 | null, with nullable types (?string) and the ?-> operator | Composer · Packagist |
| Go | Static Static, strong; structural interfaces; generics since 1.18 | Garbage collected Garbage collected (concurrent, low-latency) | Native code Compiled to a single static native binary | Goroutines and channels (CSP-style) | nil pointers, maps, slices and interfaces | Go modules, built into the go command |
| Rust | Static Static, strong, inferred; traits | Ownership Ownership and borrowing, checked at compile time | Native code Compiled to native code (LLVM) | Threads and async/await; data races are compile errors | No null: Option<T> | Cargo · crates.io |
| Swift | Static Static, strong, inferred; protocols | Reference counting Automatic reference counting (ARC) | Native code Compiled to native code (LLVM) | async/await and actors; compile-time data-race checking since Swift 6 | Optionals (String?) | Swift Package Manager |
| R | Dynamic Dynamic; everything is a vector | Garbage collected Garbage collected; copy-on-modify semantics | Interpreter Bytecode interpreter | Mostly single-threaded; parallel and future packages | NULL, plus NA as a first-class missing value | install.packages() · CRAN, Bioconductor |
| Kotlin | Static Static, strong, inferred | Garbage collected Garbage collected (by the host runtime) | Managed runtime JVM and Android; also native (LLVM), JavaScript and Wasm | Coroutines with structured concurrency | Null safety in the type system (String vs String?) | Gradle, Maven · Maven Central |
| Ruby | Dynamic Dynamic, strong, duck-typed; optional RBS and Sorbet | Garbage collected Garbage collected (generational, incremental) | Interpreter YARV bytecode interpreter with the YJIT compiler (ZJIT in 4.0) | Threads under a global VM lock, fibers, Ractors | nil, with the safe navigation operator &. | RubyGems, Bundler |
| Dart | Static Static, sound, inferred | Garbage collected Garbage collected (generational) | Native code AOT to native for release, JIT for hot reload; also JavaScript and Wasm | async/await on an event loop; isolates for parallelism | Sound null safety | dart pub · pub.dev |
| Lua | Dynamic Dynamic, strong | Garbage collected Garbage collected (incremental and generational) | Interpreter Register-based bytecode interpreter; LuaJIT for speed | Cooperative coroutines; threads come from the host | nil | LuaRocks |
| Scala | Static Static, strong, inferred; one of the richest type systems in use | Garbage collected Garbage collected | Managed runtime JVM; also Scala.js and Scala Native | Futures, actors (Akka, Pekko), effect systems (ZIO, Cats Effect) | Option[A] by convention; opt-in explicit nulls in Scala 3 | sbt, Mill, Scala CLI · Maven Central |
| Julia | Dynamic Dynamic, with optional annotations driving multiple dispatch | Garbage collected Garbage collected | Native code JIT-compiled to native code (LLVM), per method signature | Tasks, multithreading, distributed processes, GPU kernels | nothing and missing, as distinct types | Pkg · General registry |
| Zig | Static Static, strong; generics through comptime | Manual Manual, with explicit allocators and defer | Native code Compiled to native code; cross-compiles out of the box | OS threads; async rebuilt around the std.Io interface in 0.16 | No null by default: optional types (?T) | zig build · build.zig.zon |
| Haskell | Static Static, strong, inferred; type classes | Garbage collected Garbage collected; lazy evaluation by default | Native code GHC compiles to native code | Green threads and software transactional memory | No null: Maybe a | Cabal, Stack · Hackage |
| OCaml | Static Static, strong, inferred; algebraic data types and modules | Garbage collected Garbage collected; strict evaluation by default | Native code Native code or bytecode; JavaScript through js_of_ocaml | Multicore domains since OCaml 5; effect handlers and Eio for concurrency | No null: option values | opam, Dune · opam repository |
| Elixir | Gradual Dynamic, strong; since 1.20 the compiler infers and checks types gradually | Garbage collected Garbage collected, per lightweight process | Managed runtime BEAM (the Erlang VM), with a JIT | Millions of isolated processes; supervision trees | nil; tagged tuples such as {:ok, value} for results | Mix · Hex |
| Erlang | Dynamic Dynamic, strong; optional specs checked by Dialyzer | Garbage collected Garbage collected, per lightweight process | Managed runtime BEAM (the Erlang VM), with a JIT | Lightweight processes, message passing and OTP supervision | No null; atoms such as undefined and tagged tuples by convention | rebar3 · Hex |
| Clojure | Dynamic Dynamic, strong; optional spec or Malli for data shapes | Garbage collected Garbage collected; persistent immutable collections | Managed runtime JVM; ClojureScript for JavaScript, babashka for scripts | Atoms, refs (STM), agents, core.async | nil, treated as an empty collection by most functions | deps.edn, Leiningen · Clojars, Maven Central |
| F# | Static Static, strong, inferred (Hindley–Milner) | Garbage collected Garbage collected (.NET) | Managed runtime .NET runtime; Fable compiles it to JavaScript | Async and task expressions; MailboxProcessor agents | Option<T>; nullable reference types for .NET interop since F# 9 | dotnet CLI, Paket · NuGet |
| Gleam | Static Static, strong, inferred (Hindley–Milner) | Garbage collected Garbage collected (by the BEAM or the JavaScript engine) | Managed runtime Compiles to Erlang for the BEAM, or to JavaScript | BEAM processes and OTP, with typed messages | No null: Option and Result | gleam CLI · Hex |
| Odin | Static Static, strong, inferred; parametric polymorphism and distinct types | Manual Manual, with explicit allocators, defer, and an implicit context allocator | Native code Compiled to native code (LLVM); cross-compiles | OS threads and sync primitives in core:thread; no built-in async | nil pointers exist; Maybe(T), or_else and or_return handle optional values | No package manager; the compiler builds a directory as a package, with core: and vendor: collections |
10 · Profiles
All twenty-seven, in depth
Each profile covers what the language is for, the idea at its core, its strengths and weaknesses, where it scores high and low, and the same program written in it: total the paid orders per customer, then print customers from the highest total to the lowest.
Systems
You manage memory, or the compiler proves you did.
CPortable assembly, and the floor everything else stands on.
C gave Unix its portability, and Unix made C the default language of operating systems. Fifty years on, it still sits underneath nearly everything: kernels, databases, language runtimes, firmware, and the foreign-function interface every other language uses to talk to the outside world.
The big ideaTrust the programmer. C maps almost directly onto the machine and adds nothing you didn’t ask for.
Strengths
- Runs on everything with a CPU, from 8-bit microcontrollers to supercomputers.
- A small, stable language: code from the 1990s still compiles.
- The universal interface: every language can call C, and C can call anything.
Weaknesses
- No memory safety. A buffer overflow or use-after-free is one typo away.
- No standard build system, package manager or module system.
- Undefined behaviour lets compilers silently break code that looks correct.
- Reach for it for
- Firmware, kernels, drivers, and libraries that must be callable from every other language.
- Think twice for
- Anything that parses untrusted input or faces a network, unless you have the discipline and tooling of a security team.
- Created by
- Dennis Ritchie, Bell Labs
- First appeared
- 1972
- Latest
- C23 (ISO/IEC 9899:2024)
- Typing
- Static, weak; implicit conversions
- Memory
- Manual: malloc and free
- Runs as
- Compiled to native code
- Concurrency
- OS threads and atomics (pthreads, C11 threads)
- Null handling
- NULL pointers, unchecked
- Paradigms
- Procedural, Imperative
- Packages
- None official; system packages, vcpkg, Conan
- Home turf
- Systems & OS, Embedded & IoT
Scores
Popularity
- TIOBE
- #2
- PYPL
- #3
- RedMonk
- #10
- IEEE
- #8
- GitHub
- —
- JetBrains
- #10
- Stack Overflow
- #11
- Consensus
- #7 of 27
- Admired
- 45.9%
LatelyC23 brought bool, nullptr, typeof and #embed into the standard, and GCC 15 now compiles C23 by default. The next revision, C2y, adds _Countof; defer is being developed as a separate technical specification.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN(a) (sizeof(a) / sizeof((a)[0]))
typedef struct { const char *customer; int amount; bool paid; } Order;
typedef struct { const char *customer; int total; } Total;
static int by_total_desc(const void *a, const void *b) {
return ((const Total *)b)->total - ((const Total *)a)->total;
}
int main(void) {
Order orders[] = {
{"ada", 120, true}, {"grace", 75, true}, {"ada", 30, false},
{"linus", 200, true}, {"grace", 25, true},
};
Total totals[LEN(orders)];
size_t count = 0;
for (size_t i = 0; i < LEN(orders); i++) {
if (!orders[i].paid) continue;
size_t j = 0;
while (j < count && strcmp(totals[j].customer, orders[i].customer) != 0) j++;
if (j == count) totals[count++] = (Total){orders[i].customer, 0};
totals[j].total += orders[i].amount;
}
qsort(totals, count, sizeof totals[0], by_total_desc);
for (size_t j = 0; j < count; j++)
printf("%s %d\n", totals[j].customer, totals[j].total);
return 0;
}C++Zero-cost abstractions, and every feature anyone ever asked for.
C++ began as “C with Classes” and grew into the most feature-rich language in wide use. It powers game engines, browsers, databases, trading systems and most other performance-critical software, and it still gets a new standard every three years.
The big ideaZero-overhead abstraction: what you don’t use, you don’t pay for, and what you do use, you couldn’t hand-code any better.
Strengths
- Top-tier performance with high-level abstractions on top.
- Unmatched ecosystem in games, graphics, finance and high-performance computing.
- Direct access to hardware and to every C library.
Weaknesses
- An enormous language with decades of overlapping features.
- Memory safety is a matter of discipline, not a guarantee.
- Builds and dependencies are a project of their own.
- Reach for it for
- Game engines, browsers, real-time and low-latency systems, and large existing C++ codebases.
- Think twice for
- New network-facing services where a memory-safe language would do, or small teams without C++ veterans.
- Created by
- Bjarne Stroustrup, Bell Labs
- First appeared
- 1985
- Latest
- C++23; C++26 finalised in March 2026
- Typing
- Static, mostly strong; templates
- Memory
- Manual, with RAII and smart pointers
- Runs as
- Compiled to native code
- Concurrency
- Threads, atomics, futures, C++20 coroutines
- Null handling
- nullptr, unchecked; std::optional available
- Paradigms
- Multi-paradigm, Object-oriented, Generic, Procedural
- Packages
- None official; vcpkg, Conan, with CMake for builds
- Home turf
- Games, Systems & OS
Scores
Popularity
- TIOBE
- #3
- PYPL
- #3
- RedMonk
- #7
- IEEE
- #3
- GitHub
- #8
- JetBrains
- #7
- Stack Overflow
- #10
- Consensus
- #4 of 27
- Admired
- 45.8%
LatelyC++26 was technically completed in March 2026 with static reflection, contracts, std::execution and a hardened standard library: the biggest release since C++11.
#include <algorithm>
#include <map>
#include <print>
#include <string>
#include <utility>
#include <vector>
struct Order {
std::string customer;
int amount;
bool paid;
};
int main() {
const std::vector<Order> orders{
{"ada", 120, true}, {"grace", 75, true}, {"ada", 30, false},
{"linus", 200, true}, {"grace", 25, true},
};
std::map<std::string, int> totals;
for (const auto& [customer, amount, paid] : orders)
if (paid) totals[customer] += amount;
std::vector<std::pair<std::string, int>> ranked(totals.begin(), totals.end());
std::ranges::sort(ranked, std::greater{}, &std::pair<std::string, int>::second);
for (const auto& [customer, total] : ranked)
std::println("{} {}", customer, total);
}RustC++ performance, with a compiler that won’t let you shoot yourself.
Rust started as Graydon Hoare’s side project, was adopted by Mozilla, and reached 1.0 in 2015. It proved that a systems language can be memory-safe without a garbage collector, and it now ships in the Linux kernel, Android and Windows, and across the major cloud providers.
The big ideaOwnership: every value has exactly one owner and the compiler checks every borrow, so memory errors and data races become compile errors.
Strengths
- C-level speed, with memory and thread safety guaranteed at compile time.
- Cargo, Clippy, rustfmt and rust-analyzer: best-in-class tooling.
- An expressive type system with enums, pattern matching and traits.
Weaknesses
- A steep learning curve: the borrow checker changes how you design code.
- Slow compile times on large projects.
- Async Rust is powerful but adds a second layer of complexity.
- Reach for it for
- Systems software, CLIs, network services, embedded and WebAssembly, and anything replacing C or C++ where security matters.
- Think twice for
- Quick prototypes, exploratory data work, or teams that need to be productive this week.
- Created by
- Graydon Hoare; Mozilla Research
- First appeared
- 2012
- Latest
- Rust 1.99 (October 2026)
- Typing
- Static, strong, inferred; traits
- Memory
- Ownership and borrowing, checked at compile time
- Runs as
- Compiled to native code (LLVM)
- Concurrency
- Threads and async/await; data races are compile errors
- Null handling
- No null: Option<T>
- Paradigms
- Multi-paradigm, Functional, Imperative, Generic
- Packages
- Cargo · crates.io
- Home turf
- Systems & OS, CLIs & DevOps
Scores
Popularity
- TIOBE
- #10
- PYPL
- #8
- RedMonk
- #20
- IEEE
- #14
- GitHub
- —
- JetBrains
- #13
- Stack Overflow
- #12
- Consensus
- #10 of 27
- Admired
- 67.4%
LatelyThe Linux kernel dropped Rust’s “experimental” label in December 2025. Google reported in late 2025 that memory-safety bugs had fallen below 20% of Android’s vulnerabilities, down from 76% in 2019, as new code moved to Rust.
use std::collections::HashMap;
struct Order {
customer: &'static str,
amount: u32,
paid: bool,
}
fn main() {
let orders = [
Order { customer: "ada", amount: 120, paid: true },
Order { customer: "grace", amount: 75, paid: true },
Order { customer: "ada", amount: 30, paid: false },
Order { customer: "linus", amount: 200, paid: true },
Order { customer: "grace", amount: 25, paid: true },
];
let mut totals: HashMap<&str, u32> = HashMap::new();
for order in orders.iter().filter(|o| o.paid) {
*totals.entry(order.customer).or_default() += order.amount;
}
let mut ranked: Vec<_> = totals.into_iter().collect();
ranked.sort_by(|a, b| b.1.cmp(&a.1));
for (customer, total) in ranked {
println!("{customer} {total}");
}
}ZigA better C: no hidden control flow, no hidden allocations.
Zig is Andrew Kelley’s attempt at a better C: a small language with no hidden control flow, no hidden allocations and no preprocessor. It is still pre-1.0 and changes with each release, yet it already powers serious software, including the Bun runtime, the Ghostty terminal and the TigerBeetle database.
The big ideaMake everything explicit: allocators are passed in, errors are values, and compile-time code (comptime) replaces macros and generics.
Strengths
- A drop-in C compiler with seamless C interop.
- Cross-compiles to almost any target out of the box.
- comptime gives generics and metaprogramming in plain Zig.
Weaknesses
- Pre-1.0: expect breaking changes in every release.
- A small ecosystem and very few jobs.
- No memory-safety guarantees, only runtime checks in safe build modes.
- Reach for it for
- Performance-critical systems code, replacing C build toolchains, and projects where you want to control every allocation.
- Think twice for
- Anything that needs long-term API stability today, or a large hiring pool.
- Created by
- Andrew Kelley
- First appeared
- 2016
- Latest
- Zig 0.17 (October 2026)
- Typing
- Static, strong; generics through comptime
- Memory
- Manual, with explicit allocators and defer
- Runs as
- Compiled to native code; cross-compiles out of the box
- Concurrency
- OS threads; async rebuilt around the std.Io interface in 0.16
- Null handling
- No null by default: optional types (?T)
- Paradigms
- Imperative, Procedural, Generic
- Packages
- zig build · build.zig.zon
- Home turf
- Systems & OS
Scores
Popularity
- TIOBE
- #46
- PYPL
- #24
- RedMonk
- #82
- IEEE
- —
- GitHub
- —
- JetBrains
- —
- Stack Overflow
- #29
- Consensus
- #19 of 27
- Admired
- 58.3%
LatelyZig 0.16 rebuilt I/O and async around a std.Io interface that is passed in like an allocator. 0.17 reworked the build system and moved C translation out of the compiler.
const std = @import("std");
const Order = struct { customer: []const u8, amount: u32, paid: bool };
pub fn main() !void {
var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
defer _ = debug_allocator.deinit();
const gpa = debug_allocator.allocator();
const orders = [_]Order{
.{ .customer = "ada", .amount = 120, .paid = true },
.{ .customer = "grace", .amount = 75, .paid = true },
.{ .customer = "ada", .amount = 30, .paid = false },
.{ .customer = "linus", .amount = 200, .paid = true },
.{ .customer = "grace", .amount = 25, .paid = true },
};
var totals: std.StringArrayHashMapUnmanaged(u32) = .empty;
defer totals.deinit(gpa);
for (orders) |order| {
if (!order.paid) continue;
const entry = try totals.getOrPutValue(gpa, order.customer, 0);
entry.value_ptr.* += order.amount;
}
const ByTotal = struct {
values: []const u32,
pub fn lessThan(ctx: @This(), a: usize, b: usize) bool {
return ctx.values[a] > ctx.values[b];
}
};
totals.sort(ByTotal{ .values = totals.values() });
for (totals.keys(), totals.values()) |customer, total| {
std.debug.print("{s} {d}\n", .{ customer, total });
}
}OdinA calm alternative to C, built for data-oriented programming.
Bill Hall, who goes by gingerBill, started Odin in 2016 as the language he wanted for his own graphics and tools work: C’s directness without its sharp edges. It has no hidden control flow, a small set of orthogonal features, and a compiler that doubles as the build system. It is still young and its community is small, but it is used for commercial software, including the visual-effects tools from JangaFX.
The big ideaData-oriented design in the language itself: plain structs, explicit allocators passed through an implicit context, and built-in support for array programming and struct-of-arrays layouts.
Strengths
- Batteries for games and graphics: the bundled vendor: collection has bindings for OpenGL, Vulkan, raylib, SDL and more.
- Small and readable: parametric polymorphism, tagged unions and defer, without macros or exceptions.
- Built-in vector and matrix types, and #soa for struct-of-arrays layout.
Weaknesses
- Pre-1.0: the compiler ships as monthly dev builds, and breaking changes are possible.
- No package manager, and almost no ecosystem beyond what is bundled.
- Manual memory with no borrow checking: bounds checks help, but use-after-free is still on you.
- Reach for it for
- Games, graphics and native tools, and a calmer replacement for C in projects you control.
- Think twice for
- Anything that needs long-term API stability, a rich package ecosystem or a hiring pool.
- Created by
- Bill “gingerBill” Hall
- First appeared
- 2016
- Latest
- dev-2026-08 (monthly releases; no 1.0 yet)
- Typing
- Static, strong, inferred; parametric polymorphism and distinct types
- Memory
- Manual, with explicit allocators, defer, and an implicit context allocator
- Runs as
- Compiled to native code (LLVM); cross-compiles
- Concurrency
- OS threads and sync primitives in core:thread; no built-in async
- Null handling
- nil pointers exist; Maybe(T), or_else and or_return handle optional values
- Paradigms
- Imperative, Procedural, Data-oriented
- Packages
- No package manager; the compiler builds a directory as a package, with core: and vendor: collections
- Home turf
- Games, Systems & OS
Scores
Popularity
- TIOBE
- —
- PYPL
- —
- RedMonk
- —
- IEEE
- —
- GitHub
- —
- JetBrains
- —
- Stack Overflow
- #49
- Consensus
- #27 of 27
- Admired
- 82.4%
LatelyThe July 2026 build added a restricted -bedrock mode and stack canaries, and made PIE and full RELRO the Linux defaults. Odin scored 82% admired in Stack Overflow’s 2026 survey, but only about 34 respondents used it.
package main
import "core:fmt"
import "core:slice"
Order :: struct {
customer: string,
amount: int,
paid: bool,
}
Total :: struct {
customer: string,
total: int,
}
main :: proc() {
orders := []Order{
{"ada", 120, true},
{"grace", 75, true},
{"ada", 30, false},
{"linus", 200, true},
{"grace", 25, true},
}
totals := make(map[string]int)
defer delete(totals)
for order in orders {
if order.paid {
totals[order.customer] += order.amount
}
}
ranked := make([dynamic]Total, 0, len(totals))
defer delete(ranked)
for customer, total in totals {
append(&ranked, Total{customer, total})
}
slice.sort_by(ranked[:], proc(a, b: Total) -> bool {return a.total > b.total})
for row in ranked {
fmt.println(row.customer, row.total)
}
}Application
Compiled, statically typed, memory managed for you.
JavaWrite once, run anywhere, and keep running for thirty years.
Java launched with “write once, run anywhere” and became the backbone of enterprise software, Android and big data. After a slow decade it now ships every six months, and recent releases have added records, pattern matching and virtual threads without breaking old code.
The big ideaA managed, portable runtime: the JVM handles memory, optimises hot code while it runs, and executes the same bytecode everywhere.
Strengths
- The JVM is one of the most heavily optimised runtimes ever built.
- A vast, mature ecosystem: Spring, Kafka, Hadoop, Android.
- Exceptional backward compatibility and tooling.
Weaknesses
- Verbose compared with newer languages, though less so every release.
- null is everywhere.
- A framework-heavy culture can bury simple code under configuration.
- Reach for it for
- Large backend systems, long-lived enterprise software, and data infrastructure.
- Think twice for
- Tiny CLIs or serverless functions where JVM start-up time matters, unless you compile ahead of time with GraalVM.
- Created by
- James Gosling, Sun Microsystems
- First appeared
- 1995
- Latest
- JDK 27 (September 2026); JDK 25 is the current LTS
- Typing
- Static, strong, nominal; local inference with var
- Memory
- Garbage collected (G1, ZGC, and others)
- Runs as
- JVM bytecode, JIT-compiled; GraalVM native images
- Concurrency
- Platform threads, virtual threads (Java 21+), java.util.concurrent
- Null handling
- null everywhere; Optional<T> by convention
- Paradigms
- Object-oriented, Imperative, Functional (streams)
- Packages
- Maven, Gradle · Maven Central
- Home turf
- Web backends & APIs
Scores
Popularity
- TIOBE
- #4
- PYPL
- #2
- RedMonk
- #3
- IEEE
- #2
- GitHub
- #4
- JetBrains
- #3
- Stack Overflow
- #7
- Consensus
- #2 of 27
- Admired
- 38.5%
LatelyJDK 25 finalised compact source files and instance main methods, so a Java program no longer needs a class declaration; the snippet below uses them. Virtual threads, final since JDK 21, let plain blocking code scale like async code.
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.summingInt;
record Order(String customer, int amount, boolean paid) {}
void main() {
var orders = List.of(
new Order("ada", 120, true),
new Order("grace", 75, true),
new Order("ada", 30, false),
new Order("linus", 200, true),
new Order("grace", 25, true));
orders.stream()
.filter(Order::paid)
.collect(groupingBy(Order::customer, summingInt(Order::amount)))
.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.forEach(e -> IO.println(e.getKey() + " " + e.getValue()));
}C#Java’s old rival, quietly grown into one of the most complete languages around.
C# started as Microsoft’s answer to Java and has since out-evolved it, bringing async/await, LINQ and modern pattern matching to the mainstream. .NET is now open source and cross-platform, and C# runs everything from cloud services to Unity games.
The big ideaPragmatic evolution: absorb proven ideas from functional languages into a familiar, productive object-oriented core.
Strengths
- A rich, steadily evolving language with excellent IDEs.
- A fast runtime, plus Native AOT for small, quick-starting binaries.
- One language for web, desktop, mobile, cloud and games.
Weaknesses
- A large surface area, with many ways to do the same thing.
- Still seen as Windows-centric, despite a decade of cross-platform .NET.
- Nullable reference types are warnings, not guarantees.
- Reach for it for
- Enterprise backends, Windows and cross-platform desktop apps, and games in Unity or Godot.
- Think twice for
- Environments the .NET runtime can’t reach, or teams wedded to the JVM ecosystem.
- Created by
- Anders Hejlsberg, Microsoft
- First appeared
- 2000
- Latest
- C# 14 / .NET 10 LTS (November 2025)
- Typing
- Static, strong, inferred locals; reified generics
- Memory
- Garbage collected; value types and Span<T> for control
- Runs as
- .NET runtime, JIT-compiled; Native AOT available
- Concurrency
- async/await (C# popularised it), tasks, channels
- Null handling
- Nullable reference types, flagged by compiler warnings
- Paradigms
- Object-oriented, Functional, Imperative
- Packages
- dotnet CLI · NuGet
- Home turf
- Web backends & APIs, Desktop apps, Games
Scores
Popularity
- TIOBE
- #5
- PYPL
- #11
- RedMonk
- #4
- IEEE
- #5
- GitHub
- #5
- JetBrains
- #8
- Stack Overflow
- #8
- Consensus
- #5 of 27
- Admired
- 50.0%
LatelyC# 14 added extension members and the field keyword. .NET 10 runs a single .cs file with dotnet run app.cs, no project file needed, which is how the snippet below runs.
var orders = new List<Order>
{
new("ada", 120, true),
new("grace", 75, true),
new("ada", 30, false),
new("linus", 200, true),
new("grace", 25, true),
};
var totals =
from order in orders
where order.Paid
group order.Amount by order.Customer into g
let total = g.Sum()
orderby total descending
select (Customer: g.Key, Total: total);
foreach (var (customer, total) in totals)
Console.WriteLine($"{customer} {total}");
record Order(string Customer, int Amount, bool Paid);GoDeliberately boring, so that large teams can keep shipping.
Robert Griesemer, Rob Pike and Ken Thompson designed Go at Google to make large-scale server software simple to write and read. It became the language of cloud infrastructure: Docker, Kubernetes, Terraform and much of the cloud-native landscape are written in Go.
The big ideaSimplicity at scale: a small language, fast compiles, one formatting style, and concurrency built into the language.
Strengths
- Learn it in a week, then read anyone’s code.
- Goroutines and channels make concurrent servers straightforward.
- Single static binaries and very fast builds.
Weaknesses
- Verbose error handling: if err != nil, again and again.
- Deliberately limited expressiveness.
- nil pointers and data races are still possible.
- Reach for it for
- Network services, cloud infrastructure, CLIs and DevOps tooling.
- Think twice for
- GUI apps, numerical computing, or domains that reward rich type-level modelling.
- Created by
- Robert Griesemer, Rob Pike, Ken Thompson; Google
- First appeared
- 2009
- Latest
- Go 1.27 (August 2026)
- Typing
- Static, strong; structural interfaces; generics since 1.18
- Memory
- Garbage collected (concurrent, low-latency)
- Runs as
- Compiled to a single static native binary
- Concurrency
- Goroutines and channels (CSP-style)
- Null handling
- nil pointers, maps, slices and interfaces
- Paradigms
- Imperative, Procedural, Concurrent
- Packages
- Go modules, built into the go command
- Home turf
- Web backends & APIs, CLIs & DevOps, Distributed & real-time
Scores
Popularity
- TIOBE
- #11
- PYPL
- #17
- RedMonk
- #12
- IEEE
- #10
- GitHub
- #10
- JetBrains
- #9
- Stack Overflow
- #14
- Consensus
- #9 of 27
- Admired
- 49.5%
LatelyGo 1.26 made the Green Tea garbage collector the default, cutting GC overhead by 10–40%. Go 1.27 added generic methods and rebuilt encoding/json on top of json/v2.
package main
import (
"cmp"
"fmt"
"maps"
"slices"
)
type Order struct {
Customer string
Amount int
Paid bool
}
func main() {
orders := []Order{
{"ada", 120, true},
{"grace", 75, true},
{"ada", 30, false},
{"linus", 200, true},
{"grace", 25, true},
}
totals := map[string]int{}
for _, o := range orders {
if o.Paid {
totals[o.Customer] += o.Amount
}
}
customers := slices.SortedFunc(maps.Keys(totals), func(a, b string) int {
return cmp.Compare(totals[b], totals[a])
})
for _, c := range customers {
fmt.Println(c, totals[c])
}
}KotlinJava with the sharp edges filed off, and Android’s first choice.
JetBrains created Kotlin to fix Java’s pain points while staying fully interoperable with it. Google made it the preferred language for Android in 2019, and Kotlin Multiplatform now shares code across Android, iOS, desktop and the web.
The big ideaA better Java, pragmatically: null safety, concise syntax and coroutines, with seamless access to every Java library.
Strengths
- Null safety built into the type system.
- Concise, expressive syntax that Java developers pick up quickly.
- Shares code across Android, iOS, server and web with Multiplatform.
Weaknesses
- Gradle builds can be slow and complicated.
- Outside Android, the community is far smaller than Java’s.
- Compile times are longer than Java’s.
- Reach for it for
- Android apps, shared mobile logic, and JVM backends where Java feels heavy.
- Think twice for
- Teams with no JVM experience who want a minimal toolchain.
- Created by
- JetBrains
- First appeared
- 2011
- Latest
- Kotlin 2.4 (June 2026)
- Typing
- Static, strong, inferred
- Memory
- Garbage collected (by the host runtime)
- Runs as
- JVM and Android; also native (LLVM), JavaScript and Wasm
- Concurrency
- Coroutines with structured concurrency
- Null handling
- Null safety in the type system (String vs String?)
- Paradigms
- Object-oriented, Functional
- Packages
- Gradle, Maven · Maven Central
- Home turf
- Mobile apps
Scores
Popularity
- TIOBE
- #32
- PYPL
- #19
- RedMonk
- #14
- IEEE
- #13
- GitHub
- —
- JetBrains
- #10
- Stack Overflow
- #15
- Consensus
- #13 of 27
- Admired
- 43.1%
LatelyKotlin 2.4 made context parameters and explicit backing fields stable. Compose Multiplatform for iOS went stable in May 2025, so one UI codebase can now target both phones.
data class Order(val customer: String, val amount: Int, val paid: Boolean)
fun main() {
val orders = listOf(
Order("ada", 120, true),
Order("grace", 75, true),
Order("ada", 30, false),
Order("linus", 200, true),
Order("grace", 25, true),
)
orders.filter { it.paid }
.groupingBy { it.customer }
.fold(0) { total, order -> total + order.amount }
.entries
.sortedByDescending { it.value }
.forEach { (customer, total) -> println("$customer $total") }
}DartRescued from obscurity by Flutter; now one codebase for every screen.
Google first pitched Dart as a replacement for JavaScript in the browser, and that never happened. Flutter rescued it: Dart’s JIT gives instant hot reload during development and its AOT compiler gives fast native release builds. It now ships apps on iOS, Android, the web and desktop.
The big ideaA language shaped for UI work: hot reload while you build, fast native code when you ship, and sound null safety throughout.
Strengths
- Stateful hot reload makes UI iteration very fast.
- Sound null safety and a clean, familiar syntax.
- One codebase for six platforms through Flutter.
Weaknesses
- The ecosystem is mostly Flutter.
- Little use outside Flutter, so few jobs outside it.
- Macros were cancelled in 2025, leaving code generation as the workaround.
- Reach for it for
- Cross-platform apps with a custom UI, built with Flutter.
- Think twice for
- Backend services, or anything Flutter isn’t part of.
- Created by
- Lars Bak and Kasper Lund, Google
- First appeared
- 2011
- Latest
- Dart 3.13 (August 2026)
- Typing
- Static, sound, inferred
- Memory
- Garbage collected (generational)
- Runs as
- AOT to native for release, JIT for hot reload; also JavaScript and Wasm
- Concurrency
- async/await on an event loop; isolates for parallelism
- Null handling
- Sound null safety
- Paradigms
- Object-oriented, Functional
- Packages
- dart pub · pub.dev
- Home turf
- Mobile apps
Scores
Popularity
- TIOBE
- #27
- PYPL
- #18
- RedMonk
- #18
- IEEE
- #15
- GitHub
- —
- JetBrains
- #14
- Stack Overflow
- #20
- Consensus
- #15 of 27
- Admired
- 42.3%
LatelyThe Dart team cancelled macros in January 2025 after years of work. Dot shorthands arrived in 3.10 and primary constructors in 3.13.
typedef Order = ({String customer, int amount, bool paid});
void main() {
const List<Order> orders = [
(customer: 'ada', amount: 120, paid: true),
(customer: 'grace', amount: 75, paid: true),
(customer: 'ada', amount: 30, paid: false),
(customer: 'linus', amount: 200, paid: true),
(customer: 'grace', amount: 25, paid: true),
];
final totals = <String, int>{};
for (final (:customer, :amount, :paid) in orders) {
if (paid) {
totals.update(customer, (sum) => sum + amount, ifAbsent: () => amount);
}
}
final ranked = totals.entries.toList()
..sort((a, b) => b.value.compareTo(a.value));
for (final MapEntry(:key, :value) in ranked) {
print('$key $value');
}
}SwiftApple’s safe, fast successor to Objective-C.
Apple introduced Swift in 2014 as a modern replacement for Objective-C. It combines value types, optionals and protocol-oriented design with native performance, and Swift 6 added compile-time data-race checking. It also runs on Linux, Windows, Android and microcontrollers, though most of its use is still on Apple platforms.
The big ideaSafe by default, fast by design: optionals instead of null, value types everywhere, and a compiler that catches data races.
Strengths
- Modern, safe and expressive syntax.
- Native performance with no garbage-collection pauses.
- First-class access to Apple’s frameworks.
Weaknesses
- Jobs and libraries are concentrated on Apple platforms.
- Language churn: Swift 6’s strict concurrency was a hard migration.
- Compile times, and Xcode, can frustrate.
- Reach for it for
- iOS, macOS, watchOS and visionOS apps.
- Think twice for
- Cross-platform products where Apple is one target among many, unless you’re betting on Swift’s newer Android and server support.
- Created by
- Chris Lattner, Apple
- First appeared
- 2014
- Latest
- Swift 6.4 (September 2026)
- Typing
- Static, strong, inferred; protocols
- Memory
- Automatic reference counting (ARC)
- Runs as
- Compiled to native code (LLVM)
- Concurrency
- async/await and actors; compile-time data-race checking since Swift 6
- Null handling
- Optionals (String?)
- Paradigms
- Protocol-oriented, Object-oriented, Functional
- Packages
- Swift Package Manager
- Home turf
- Mobile apps
Scores
Popularity
- TIOBE
- #14
- PYPL
- #10
- RedMonk
- #11
- IEEE
- #16
- GitHub
- —
- JetBrains
- #14
- Stack Overflow
- #18
- Consensus
- #11 of 27
- Admired
- 48.5%
LatelySwift 6.2 softened strict concurrency with “approachable concurrency” defaults. An official Android workgroup is building Android support, and Embedded Swift now targets microcontrollers.
struct Order {
let customer: String
let amount: Int
let paid: Bool
}
let orders = [
Order(customer: "ada", amount: 120, paid: true),
Order(customer: "grace", amount: 75, paid: true),
Order(customer: "ada", amount: 30, paid: false),
Order(customer: "linus", amount: 200, paid: true),
Order(customer: "grace", amount: 25, paid: true),
]
let totals = orders
.filter(\.paid)
.reduce(into: [String: Int]()) { $0[$1.customer, default: 0] += $1.amount }
for (customer, total) in totals.sorted(by: { $0.value > $1.value }) {
print(customer, total)
}Web platform
Born in, or for, the browser and the web server.
JavaScriptDesigned in ten days; now runs on every device with a screen.
Brendan Eich wrote the first version of JavaScript in ten days in 1995. It became the only language every web browser runs, then spread to servers with Node.js, desktops with Electron and phones with React Native. It is still the most used language in most developer surveys.
The big ideaA dynamic, event-driven language with first-class functions, running wherever there is a browser engine.
Strengths
- Runs everywhere, with nothing for users to install.
- The largest package registry in the world.
- Fast JIT-compiled engines and a huge talent pool.
Weaknesses
- Weak typing and coercion quirks: [] + {} is a string.
- Tooling churn: bundlers, runtimes and package managers multiply.
- Deep dependency trees, and the supply-chain risk that comes with them.
- Reach for it for
- Anything that runs in a browser, small scripts, and full-stack web apps in one language.
- Think twice for
- Large codebases without types. Reach for TypeScript instead.
- Created by
- Brendan Eich, Netscape
- First appeared
- 1995
- Latest
- ECMAScript 2026 (June 2026)
- Typing
- Dynamic, weak (implicit coercion)
- Memory
- Garbage collected
- Runs as
- JIT-compiled by the engine (V8, SpiderMonkey, JavaScriptCore)
- Concurrency
- Single-threaded event loop, promises, async/await; workers
- Null handling
- Both null and undefined
- Paradigms
- Multi-paradigm, Prototype-based, Functional, Event-driven
- Packages
- npm, pnpm, Yarn, Bun · npm registry
- Home turf
- Web frontends
Scores
Popularity
- TIOBE
- #6
- PYPL
- #6
- RedMonk
- #1
- IEEE
- #6
- GitHub
- #3
- JetBrains
- #1
- Stack Overflow
- #1
- Consensus
- #3 of 27
- Admired
- 42.0%
LatelyES2026 added Math.sumPrecise, Error.isError and base64 helpers on Uint8Array. Temporal, the long-awaited replacement for Date, is finished and scheduled for ES2027.
const orders = [
{ customer: "ada", amount: 120, paid: true },
{ customer: "grace", amount: 75, paid: true },
{ customer: "ada", amount: 30, paid: false },
{ customer: "linus", amount: 200, paid: true },
{ customer: "grace", amount: 25, paid: true },
];
const totals = new Map();
for (const { customer, amount, paid } of orders) {
if (paid) totals.set(customer, (totals.get(customer) ?? 0) + amount);
}
[...totals]
.sort(([, a], [, b]) => b - a)
.forEach(([customer, total]) => console.log(customer, total));PHPThe language the web’s long tail runs on, and better than its reputation.
PHP began as Rasmus Lerdorf’s “Personal Home Page” tools and grew into the server language of the early web. It still runs a large share of all websites, every WordPress install among them. Modern PHP, with types, a JIT and frameworks like Laravel and Symfony, is a very different language from its reputation.
The big ideaShared-nothing simplicity: every request starts fresh, so there is no state to leak and deploying is copying files.
Strengths
- Easy to host and deploy almost anywhere.
- Mature frameworks: Laravel, Symfony, WordPress.
- Modern PHP is fast and increasingly well typed.
Weaknesses
- An inconsistent standard library, inherited from its early years.
- Its reputation still lags behind reality, which affects hiring.
- Long-running and concurrent workloads need extensions such as Swoole.
- Reach for it for
- Content sites, e-commerce and CRUD web applications, especially with Laravel or WordPress.
- Think twice for
- Real-time systems, CPU-heavy work, or anything outside the web.
- Created by
- Rasmus Lerdorf
- First appeared
- 1995
- Latest
- PHP 8.5 (November 2025); 8.6 due November 2026
- Typing
- Dynamic, with type declarations enforced at runtime
- Memory
- Reference counting with a cycle collector, reset per request
- Runs as
- Zend Engine bytecode with OPcache and an optional JIT
- Concurrency
- Shared-nothing request processes; Fibers since 8.1
- Null handling
- null, with nullable types (?string) and the ?-> operator
- Paradigms
- Object-oriented, Imperative, Procedural
- Packages
- Composer · Packagist
- Home turf
- Web backends & APIs
Scores
Popularity
- TIOBE
- #12
- PYPL
- #7
- RedMonk
- #4
- IEEE
- #12
- GitHub
- #6
- JetBrains
- #12
- Stack Overflow
- #13
- Consensus
- #8 of 27
- Admired
- 35.7%
LatelyPHP 8.4 added property hooks and asymmetric visibility. PHP 8.5 added the pipe operator (|>) and a built-in URI extension.
<?php
final readonly class Order
{
public function __construct(
public string $customer,
public int $amount,
public bool $paid,
) {}
}
$orders = [
new Order('ada', 120, true),
new Order('grace', 75, true),
new Order('ada', 30, false),
new Order('linus', 200, true),
new Order('grace', 25, true),
];
$totals = [];
foreach ($orders as $order) {
if ($order->paid) {
$totals[$order->customer] = ($totals[$order->customer] ?? 0) + $order->amount;
}
}
arsort($totals);
foreach ($totals as $customer => $total) {
echo "$customer $total\n";
}TypeScriptJavaScript with a type system good enough to become the default.
Anders Hejlsberg, who also designed C#, led the creation of TypeScript to make large JavaScript codebases manageable. Its structural, gradual type system won: most major frameworks now scaffold projects in TypeScript, and in 2025 it became the most used language on GitHub by monthly contributors.
The big ideaDescribe JavaScript as people actually write it: a structural type system that models existing patterns, then disappears at runtime.
Strengths
- Catches whole categories of bugs before the code runs.
- A superb editor experience: completion, refactoring, navigation.
- Full access to the JavaScript ecosystem.
Weaknesses
- The type system is deliberately unsound, and any switches it off.
- Configuration and build setup add friction.
- Type-level code can become a puzzle of its own.
- Reach for it for
- Any JavaScript project bigger than a script: frontends, Node backends, libraries.
- Think twice for
- Tiny one-off scripts, or teams who will fight the compiler with any.
- Created by
- Anders Hejlsberg, Microsoft
- First appeared
- 2012
- Latest
- TypeScript 7.0 (July 2026)
- Typing
- Static, structural, inferred; deliberately unsound
- Memory
- Garbage collected (runs as JavaScript)
- Runs as
- Compiled to JavaScript, types erased; compiler rewritten in Go for 7.0
- Concurrency
- Same as JavaScript: event loop, promises, workers
- Null handling
- Strict null checks make null and undefined explicit
- Paradigms
- Multi-paradigm, Object-oriented, Functional
- Packages
- npm and friends · npm registry
- Home turf
- Web frontends, Web backends & APIs
Scores
Popularity
- TIOBE
- #38
- PYPL
- #12
- RedMonk
- #6
- IEEE
- #7
- GitHub
- #1
- JetBrains
- #5
- Stack Overflow
- #6
- Consensus
- #6 of 27
- Admired
- 53.0%
LatelyTypeScript 7.0 replaced the JavaScript-based compiler with a native port written in Go. It is roughly ten times faster on large codebases: type-checking VS Code’s 1.5 million lines dropped from 77.8 to 7.5 seconds.
interface Order {
customer: string;
amount: number;
paid: boolean;
}
const orders: Order[] = [
{ customer: "ada", amount: 120, paid: true },
{ customer: "grace", amount: 75, paid: true },
{ customer: "ada", amount: 30, paid: false },
{ customer: "linus", amount: 200, paid: true },
{ customer: "grace", amount: 25, paid: true },
];
const totals = orders
.filter((order) => order.paid)
.reduce<Record<string, number>>((acc, { customer, amount }) => {
acc[customer] = (acc[customer] ?? 0) + amount;
return acc;
}, {});
Object.entries(totals)
.sort(([, a], [, b]) => b - a)
.forEach(([customer, total]) => console.log(customer, total));Dynamic
Optimised for the programmer’s time over the machine’s.
PythonExecutable pseudocode that ended up running the AI boom.
Guido van Rossum designed Python around readability, with significant indentation and a “batteries included” standard library. It became the default language for scripting, teaching, data science and machine learning, and in 2026 it leads almost every popularity ranking.
The big ideaThere should be one obvious way to do it: readable code first, and when speed matters, call into C.
Strengths
- The gentlest learning curve of any mainstream language.
- An unrivalled ecosystem for data, ML and science: NumPy, pandas, PyTorch.
- Glue for everything: scripts, automation, APIs.
Weaknesses
- Slow in pure Python; the heavy lifting happens in C, C++ or Rust.
- The GIL kept threads off multiple cores for three decades.
- Packaging was painful for years, though uv is fixing it.
- Reach for it for
- Data analysis, machine learning, automation, scripting, and backends where developer time matters more than CPU time.
- Think twice for
- Mobile apps, browser code and CPU-bound hot paths.
- Created by
- Guido van Rossum
- First appeared
- 1991
- Latest
- Python 3.15 (October 2026)
- Typing
- Dynamic, strong; optional type hints checked by external tools
- Memory
- Reference counting plus a cycle-detecting collector
- Runs as
- CPython bytecode interpreter; experimental JIT since 3.13
- Concurrency
- asyncio, threads (GIL, or the opt-in free-threaded build), processes
- Null handling
- None, caught only by type checkers
- Paradigms
- Multi-paradigm, Object-oriented, Imperative, Functional
- Packages
- pip, uv, Poetry · PyPI
- Home turf
- Data & ML, Scientific computing, Scripting & automation
Scores
Popularity
- TIOBE
- #1
- PYPL
- #1
- RedMonk
- #2
- IEEE
- #1
- GitHub
- #2
- JetBrains
- #2
- Stack Overflow
- #4
- Consensus
- #1 of 27
- Admired
- 50.6%
LatelyPython 3.14 made the free-threaded (no-GIL) build officially supported, though it is still opt-in. 3.15 adds explicit lazy imports and makes UTF-8 the default. Astral’s uv has become the fast default for environments and packages.
from collections import Counter
from dataclasses import dataclass
@dataclass
class Order:
customer: str
amount: int
paid: bool
orders = [
Order("ada", 120, True),
Order("grace", 75, True),
Order("ada", 30, False),
Order("linus", 200, True),
Order("grace", 25, True),
]
totals = Counter()
for order in orders:
if order.paid:
totals[order.customer] += order.amount
for customer, total in totals.most_common():
print(customer, total)LuaA tiny language designed to live inside other programs.
Lua was created at PUC-Rio in Brazil as a small, embeddable scripting language. The whole interpreter is a little portable C, so it lives inside other software: game engines, Roblox (as Luau), Neovim, Redis, nginx through OpenResty, and countless devices.
The big ideaMechanisms, not policies: one data structure (the table), first-class functions, coroutines, and a clean C API for embedding.
Strengths
- Tiny, quick to embed and easy to sandbox.
- A simple language you can learn in an afternoon.
- LuaJIT is one of the fastest dynamic-language runtimes.
Weaknesses
- A thin standard library and ecosystem.
- Arrays start at 1 and variables are global by default.
- Fragmented versions: 5.1 (LuaJIT, Luau) versus 5.4 and 5.5.
- Reach for it for
- Scripting inside a game, editor or application you control.
- Think twice for
- Standalone applications that need a large standard library.
- Created by
- Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes; PUC-Rio
- First appeared
- 1993
- Latest
- Lua 5.5 (December 2025)
- Typing
- Dynamic, strong
- Memory
- Garbage collected (incremental and generational)
- Runs as
- Register-based bytecode interpreter; LuaJIT for speed
- Concurrency
- Cooperative coroutines; threads come from the host
- Null handling
- nil
- Paradigms
- Multi-paradigm, Imperative, Prototype-based
- Packages
- LuaRocks
- Home turf
- Games, Scripting & automation
Scores
Popularity
- TIOBE
- #35
- PYPL
- #20
- RedMonk
- —
- IEEE
- #21
- GitHub
- —
- JetBrains
- #16
- Stack Overflow
- #16
- Consensus
- #16 of 27
- Admired
- 40.8%
LatelyLua 5.5 added explicit global declarations and a far more memory-efficient array representation. GitHub named Roblox’s Luau its fastest-growing language of 2025.
local orders = {
{ customer = "ada", amount = 120, paid = true },
{ customer = "grace", amount = 75, paid = true },
{ customer = "ada", amount = 30, paid = false },
{ customer = "linus", amount = 200, paid = true },
{ customer = "grace", amount = 25, paid = true },
}
local totals = {}
for _, order in ipairs(orders) do
if order.paid then
totals[order.customer] = (totals[order.customer] or 0) + order.amount
end
end
local ranked = {}
for customer, total in pairs(totals) do
ranked[#ranked + 1] = { customer = customer, total = total }
end
table.sort(ranked, function(a, b) return a.total > b.total end)
for _, row in ipairs(ranked) do
print(row.customer, row.total)
endRubyOptimised for programmer happiness; the language that gave us Rails.
Yukihiro Matsumoto designed Ruby to make programmers happy, taking Smalltalk’s object model and Perl’s practicality. Ruby on Rails defined how web apps were built for a decade, and still powers GitHub, Shopify and many established companies.
The big ideaEverything is an object, and the language bends to the programmer: blocks, open classes and metaprogramming make DSLs natural.
Strengths
- Beautiful, expressive syntax.
- Rails is still one of the fastest ways to ship a web product.
- Strong conventions and a strong testing culture.
Weaknesses
- Slower than compiled languages, although YJIT helps.
- A shrinking community and job market.
- Metaprogramming can make large codebases hard to follow.
- Reach for it for
- Web products and startups that want Rails’ conventions and speed of delivery.
- Think twice for
- CPU-bound or highly concurrent workloads.
- Created by
- Yukihiro “Matz” Matsumoto
- First appeared
- 1995
- Latest
- Ruby 4.0 (December 2025)
- Typing
- Dynamic, strong, duck-typed; optional RBS and Sorbet
- Memory
- Garbage collected (generational, incremental)
- Runs as
- YARV bytecode interpreter with the YJIT compiler (ZJIT in 4.0)
- Concurrency
- Threads under a global VM lock, fibers, Ractors
- Null handling
- nil, with the safe navigation operator &.
- Paradigms
- Object-oriented, Functional, Metaprogramming
- Packages
- RubyGems, Bundler
- Home turf
- Web backends & APIs
Scores
Popularity
- TIOBE
- #28
- PYPL
- #14
- RedMonk
- #9
- IEEE
- #17
- GitHub
- —
- JetBrains
- #16
- Stack Overflow
- #19
- Consensus
- #14 of 27
- Admired
- 42.4%
LatelyRuby 4.0 shipped on the language’s 30th anniversary with ZJIT, an experimental successor to YJIT, and Ruby::Box for isolating code.
Order = Data.define(:customer, :amount, :paid)
orders = [
Order.new("ada", 120, true),
Order.new("grace", 75, true),
Order.new("ada", 30, false),
Order.new("linus", 200, true),
Order.new("grace", 25, true),
]
orders
.select(&:paid)
.group_by(&:customer)
.transform_values { |list| list.sum(&:amount) }
.sort_by { |_, total| -total }
.each { |customer, total| puts "#{customer} #{total}" }Scientific
Arrays, statistics, and notebooks first.
RThe statistician’s lingua franca, with a package for every published method.
Ross Ihaka and Robert Gentleman created R as an open-source take on the S language for statistics. It is the working language of statisticians, epidemiologists and bioinformaticians, with more than twenty thousand packages on CRAN and thousands more on Bioconductor.
The big ideaAnalysis as a conversation: vectors, data frames and model formulas are built in, and every statistical method is a function call away.
Strengths
- The deepest library of statistical methods anywhere.
- ggplot2 and the tidyverse set the standard for data workflows.
- Excellent for reproducible reports with R Markdown and Quarto.
Weaknesses
- Quirky, inconsistent language design.
- Slow and memory-hungry on large data without specialised packages.
- Little use outside data analysis.
- Reach for it for
- Statistics, biostatistics, academic research and exploratory analysis.
- Think twice for
- Production services, or anything that isn’t analysis.
- Created by
- Ross Ihaka and Robert Gentleman
- First appeared
- 1993
- Latest
- R 4.6 (April 2026)
- Typing
- Dynamic; everything is a vector
- Memory
- Garbage collected; copy-on-modify semantics
- Runs as
- Bytecode interpreter
- Concurrency
- Mostly single-threaded; parallel and future packages
- Null handling
- NULL, plus NA as a first-class missing value
- Paradigms
- Functional, Array, Object-oriented (S3, S4, R5)
- Packages
- install.packages() · CRAN, Bioconductor
- Home turf
- Data & ML, Scientific computing
Scores
Popularity
- TIOBE
- #8
- PYPL
- #4
- RedMonk
- #13
- IEEE
- #11
- GitHub
- —
- JetBrains
- —
- Stack Overflow
- #21
- Consensus
- #12 of 27
- Admired
- 40.7%
LatelyR 4.6 made C++20 the default standard for compiled package code. Posit’s Positron IDE is giving R a modern, polyglot development environment.
orders <- data.frame(
customer = c("ada", "grace", "ada", "linus", "grace"),
amount = c(120, 75, 30, 200, 25),
paid = c(TRUE, TRUE, FALSE, TRUE, TRUE)
)
paid_orders <- orders[orders$paid, ]
totals <- aggregate(amount ~ customer, data = paid_orders, FUN = sum)
totals[order(-totals$amount), ]JuliaReads like Python, runs like C, built for numerical computing.
Julia was created at MIT to solve the two-language problem: prototyping in Python or MATLAB, then rewriting in C for speed. It compiles each function for the argument types it is called with, so high-level numerical code runs close to native speed.
The big ideaMultiple dispatch: functions specialise on the types of all their arguments, so generic numerical code is both composable and fast.
Strengths
- Near-C speed for numerical code without leaving the language.
- Multiple dispatch makes libraries compose unusually well.
- Excellent for differential equations, optimisation and GPU computing.
Weaknesses
- Compilation latency (“time to first plot”), although much improved.
- A small ecosystem and job market outside science.
- Hard to ship as a small standalone binary.
- Reach for it for
- Scientific computing, simulation, optimisation, and research code that has to be fast.
- Think twice for
- General web or mobile development, or teams that need a large hiring pool.
- Created by
- Jeff Bezanson, Stefan Karpinski, Viral B. Shah, Alan Edelman
- First appeared
- 2012
- Latest
- Julia 1.13 (2026)
- Typing
- Dynamic, with optional annotations driving multiple dispatch
- Memory
- Garbage collected
- Runs as
- JIT-compiled to native code (LLVM), per method signature
- Concurrency
- Tasks, multithreading, distributed processes, GPU kernels
- Null handling
- nothing and missing, as distinct types
- Paradigms
- Multiple dispatch, Functional, Array
- Packages
- Pkg · General registry
- Home turf
- Scientific computing
Scores
Popularity
- TIOBE
- #18
- PYPL
- #21
- RedMonk
- —
- IEEE
- #31
- GitHub
- —
- JetBrains
- —
- Stack Overflow
- #39
- Consensus
- #18 of 27
- Admired
- 47.4%
LatelyJulia 1.12 added an experimental --trim option for much smaller compiled binaries. In October 2026 Julia returned to TIOBE’s top 20.
struct Order
customer::String
amount::Int
paid::Bool
end
orders = [
Order("ada", 120, true),
Order("grace", 75, true),
Order("ada", 30, false),
Order("linus", 200, true),
Order("grace", 25, true),
]
totals = Dict{String,Int}()
for o in orders
o.paid && (totals[o.customer] = get(totals, o.customer, 0) + o.amount)
end
for (customer, total) in sort(collect(totals); by = last, rev = true)
println(customer, " ", total)
endFunctional
Immutable data, with functions as the unit of design.
ErlangIsolated processes and supervision for systems that must stay up.
Joe Armstrong, Robert Virding and Mike Williams developed Erlang at Ericsson for telephone systems that had to keep running through failures. Its lightweight processes, message passing and OTP libraries now support messaging services, databases and distributed backends. Elixir and Gleam share its BEAM runtime.
The big ideaIsolate failures in small processes, pass messages between them, and let supervisors restart the parts that fail.
Strengths
- OTP provides established patterns for supervision, servers and application lifecycles.
- Lightweight processes have separate heaps and communicate without shared mutable state.
- Built-in support for distributed nodes, remote inspection and hot code loading.
Weaknesses
- Dynamic types leave many mistakes to runtime; Dialyzer catches only some of them.
- CPU-heavy work is slower than in languages compiled for numerical workloads.
- A small hiring pool and unfamiliar syntax for most developers.
- Reach for it for
- Messaging, telecoms, distributed backends, and services that must recover from partial failures.
- Think twice for
- Numerical computing, GUI applications, or hard real-time systems with strict execution deadlines.
- Created by
- Joe Armstrong, Robert Virding and Mike Williams, Ericsson
- First appeared
- 1986
- Latest
- Erlang/OTP 29.1.1 (September 2026)
- Typing
- Dynamic, strong; optional specs checked by Dialyzer
- Memory
- Garbage collected, per lightweight process
- Runs as
- BEAM (the Erlang VM), with a JIT
- Concurrency
- Lightweight processes, message passing and OTP supervision
- Null handling
- No null; atoms such as undefined and tagged tuples by convention
- Paradigms
- Functional, Concurrent, Distributed
- Packages
- rebar3 · Hex
- Home turf
- Web backends & APIs, Distributed & real-time
Scores
Popularity
- TIOBE
- 51–100
- PYPL
- —
- RedMonk
- —
- IEEE
- #52
- GitHub
- —
- JetBrains
- —
- Stack Overflow
- #38
- Consensus
- #23 of 27
- Admired
- 49.1%
LatelyOTP 29 introduced experimental native records and multi-valued comprehensions, improved the JIT, and added support for testing examples in module documentation.
#!/usr/bin/env escript
main(_) ->
Orders = [
#{customer => "ada", amount => 120, paid => true},
#{customer => "grace", amount => 75, paid => true},
#{customer => "ada", amount => 30, paid => false},
#{customer => "linus", amount => 200, paid => true},
#{customer => "grace", amount => 25, paid => true}
],
Totals = lists:foldl(
fun(#{paid := true, customer := Customer, amount := Amount}, Acc) ->
maps:update_with(Customer, fun(Total) -> Total + Amount end, Amount, Acc);
(_, Acc) -> Acc
end,
#{}, Orders),
Ranked = lists:sort(fun({_, A}, {_, B}) -> A >= B end, maps:to_list(Totals)),
lists:foreach(fun({Customer, Total}) ->
io:format("~s ~B~n", [Customer, Total])
end, Ranked).HaskellPure, lazy, and the source of half of modern language design.
Haskell was designed by a committee in 1990 to consolidate research on lazy functional languages. Its influence far exceeds its usage: type classes, monads and much of what makes Rust, Swift, Scala and modern C# expressive can be traced back to it.
The big ideaPurity and types: a function has no side effects unless its type says so, and the compiler checks the rest.
Strengths
- A powerful type system that rules out entire classes of bugs.
- Fearless refactoring: if it compiles, it usually works.
- Excellent concurrency, with software transactional memory.
Weaknesses
- A steep learning curve full of abstract concepts.
- Laziness makes performance and memory use hard to predict.
- A small job market and uneven library quality.
- Reach for it for
- Compilers, financial systems, and domains where correctness matters more than hiring.
- Think twice for
- Teams without functional programming experience who are under delivery pressure.
- Created by
- A committee of researchers
- First appeared
- 1990
- Latest
- GHC 9.14 (December 2025)
- Typing
- Static, strong, inferred; type classes
- Memory
- Garbage collected; lazy evaluation by default
- Runs as
- GHC compiles to native code
- Concurrency
- Green threads and software transactional memory
- Null handling
- No null: Maybe a
- Paradigms
- Purely functional, Lazy
- Packages
- Cabal, Stack · Hackage
- Home turf
Scores
Popularity
- TIOBE
- #41
- PYPL
- #27
- RedMonk
- —
- IEEE
- #30
- GitHub
- —
- JetBrains
- —
- Stack Overflow
- #34
- Consensus
- #20 of 27
- Admired
- 47.8%
LatelyGHC adopted a long-term-support release policy in 2025, and 9.14 is its first LTS release.
import Data.List (sortOn)
import qualified Data.Map.Strict as Map
import Data.Ord (Down (..))
data Order = Order {customer :: String, amount :: Int, paid :: Bool}
orders :: [Order]
orders =
[ Order "ada" 120 True,
Order "grace" 75 True,
Order "ada" 30 False,
Order "linus" 200 True,
Order "grace" 25 True
]
main :: IO ()
main = mapM_ (\(name, total) -> putStrLn (name ++ " " ++ show total)) ranked
where
totals = Map.fromListWith (+) [(customer o, amount o) | o <- orders, paid o]
ranked = sortOn (Down . snd) (Map.toList totals)OCamlInferred types, pattern matching and native code in the ML tradition.
Xavier Leroy and colleagues at INRIA developed OCaml from the Caml branch of ML, adding an object system in 1996. It combines inferred static types and pattern matching with native compilation and strict evaluation. It is used for compilers, program analysis and financial systems, and directly influenced F#.
The big ideaDescribe data with variants and records, handle each case with pattern matching, and use modules to organise larger programs.
Strengths
- Type inference and algebraic data types catch mistakes with few annotations.
- Native compilation and strict evaluation make performance easier to predict than in a lazy language.
- Modules and functors support reusable libraries with explicit interfaces.
Weaknesses
- A smaller library ecosystem and hiring pool than the mainstream languages.
- Advanced modules, objects and polymorphic variants take time to learn.
- Multicore code can still have data races; the type checker does not enforce ownership.
- Reach for it for
- Compilers, static analysis, financial systems, and typed backend or command-line tools.
- Think twice for
- Mobile interfaces, hard real-time code, or teams that need a large hiring pool.
- Created by
- Xavier Leroy and colleagues, INRIA
- First appeared
- 1996
- Latest
- OCaml 5.5.1 (September 2026)
- Typing
- Static, strong, inferred; algebraic data types and modules
- Memory
- Garbage collected; strict evaluation by default
- Runs as
- Native code or bytecode; JavaScript through js_of_ocaml
- Concurrency
- Multicore domains since OCaml 5; effect handlers and Eio for concurrency
- Null handling
- No null: option values
- Paradigms
- Functional-first, Imperative, Object-oriented
- Packages
- opam, Dune · opam repository
- Home turf
- CLIs & DevOps
Scores
Popularity
- TIOBE
- #26
- PYPL
- —
- RedMonk
- —
- IEEE
- #40
- GitHub
- —
- JetBrains
- —
- Stack Overflow
- #44
- Consensus
- #21 of 27
- Admired
- 51.5%
LatelyOCaml 5 brought multicore domains and effect handlers. Version 5.5 added module-dependent functions and a relocatable compiler; 5.5.1 fixes bugs and hardens Marshal.
module Totals = Map.Make (String)
type order = { customer : string; amount : int; paid : bool }
let orders = [
{ customer = "ada"; amount = 120; paid = true };
{ customer = "grace"; amount = 75; paid = true };
{ customer = "ada"; amount = 30; paid = false };
{ customer = "linus"; amount = 200; paid = true };
{ customer = "grace"; amount = 25; paid = true };
]
let () =
orders
|> List.fold_left (fun totals order ->
if not order.paid then totals
else Totals.update order.customer
(fun current -> Some (Option.value current ~default:0 + order.amount))
totals) Totals.empty
|> Totals.bindings
|> List.sort (fun (_, a) (_, b) -> Int.compare b a)
|> List.iter (fun (customer, total) -> Printf.printf "%s %d\n" customer total)ScalaObjects and functions fused on the JVM, with all the power that implies.
Martin Odersky created Scala at EPFL to unify object-oriented and functional programming on the JVM. It powered the big-data wave through Apache Spark and the early Kafka, and Scala 3 redesigned the language with cleaner syntax on a new theoretical foundation.
The big ideaObjects and functions are two sides of one coin, and a strong type system lets you express both precisely.
Strengths
- An extremely expressive type system and syntax.
- Full access to the JVM ecosystem.
- Strong in data engineering (Spark) and effect systems (ZIO, Cats Effect).
Weaknesses
- Complexity: many paradigms and many ways to write the same thing.
- The move from Scala 2 to Scala 3 split the community.
- A shrinking job market as Kotlin and Java improved.
- Reach for it for
- Data engineering with Spark, and teams that want advanced functional programming on the JVM.
- Think twice for
- Teams that need a simple, uniform codebase.
- Created by
- Martin Odersky, EPFL
- First appeared
- 2004
- Latest
- Scala 3.9 LTS (September 2026)
- Typing
- Static, strong, inferred; one of the richest type systems in use
- Memory
- Garbage collected
- Runs as
- JVM; also Scala.js and Scala Native
- Concurrency
- Futures, actors (Akka, Pekko), effect systems (ZIO, Cats Effect)
- Null handling
- Option[A] by convention; opt-in explicit nulls in Scala 3
- Paradigms
- Functional, Object-oriented
- Packages
- sbt, Mill, Scala CLI · Maven Central
- Home turf
Scores
Popularity
- TIOBE
- #40
- PYPL
- #22
- RedMonk
- #14
- IEEE
- #28
- GitHub
- —
- JetBrains
- #16
- Stack Overflow
- #35
- Consensus
- #17 of 27
- Admired
- 39.2%
LatelyScala 3.9 is the new long-term-support release, and 3.8 shipped a standard library compiled with Scala 3 itself.
case class Order(customer: String, amount: Int, paid: Boolean)
@main def report(): Unit =
val orders = List(
Order("ada", 120, true),
Order("grace", 75, true),
Order("ada", 30, false),
Order("linus", 200, true),
Order("grace", 25, true),
)
orders
.filter(_.paid)
.groupMapReduce(_.customer)(_.amount)(_ + _)
.toList
.sortBy(-_._2)
.foreach((customer, total) => println(s"$customer $total"))F#ML-style functional programming with all of .NET behind it.
Don Syme at Microsoft Research brought the ML family to .NET with F#. It is functional-first, with type inference, discriminated unions and pipelines, and can still use every .NET library. It has a loyal following in finance and other data-heavy domains.
The big ideaMake illegal states unrepresentable: model the domain with types, and compose behaviour with pipelines.
Strengths
- Concise, readable functional code with strong type inference.
- All of .NET available, plus excellent scripting with .fsx files.
- A natural fit for domain modelling.
Weaknesses
- A small community, and only modest investment from Microsoft.
- Tooling trails C#.
- Few jobs outside finance and specialist shops.
- Reach for it for
- Domain-heavy backends, financial modelling, data scripts, and .NET teams who want functional programming.
- Think twice for
- Organisations that need to hire many developers quickly.
- Created by
- Don Syme, Microsoft Research
- First appeared
- 2005
- Latest
- F# 10 / .NET 10 (November 2025)
- Typing
- Static, strong, inferred (Hindley–Milner)
- Memory
- Garbage collected (.NET)
- Runs as
- .NET runtime; Fable compiles it to JavaScript
- Concurrency
- Async and task expressions; MailboxProcessor agents
- Null handling
- Option<T>; nullable reference types for .NET interop since F# 9
- Paradigms
- Functional-first, Object-oriented
- Packages
- dotnet CLI, Paket · NuGet
- Home turf
Scores
Popularity
- TIOBE
- 51–100
- PYPL
- —
- RedMonk
- —
- IEEE
- —
- GitHub
- —
- JetBrains
- —
- Stack Overflow
- #43
- Consensus
- #25 of 27
- Admired
- 48.3%
LatelyF# 9 added nullable reference types for safer .NET interop. F# 10 brought parallel compilation in preview and scoped warning control.
type Order = { Customer: string; Amount: int; Paid: bool }
let orders =
[ { Customer = "ada"; Amount = 120; Paid = true }
{ Customer = "grace"; Amount = 75; Paid = true }
{ Customer = "ada"; Amount = 30; Paid = false }
{ Customer = "linus"; Amount = 200; Paid = true }
{ Customer = "grace"; Amount = 25; Paid = true } ]
orders
|> List.filter _.Paid
|> List.groupBy _.Customer
|> List.map (fun (customer, items) -> customer, List.sumBy _.Amount items)
|> List.sortByDescending snd
|> List.iter (fun (customer, total) -> printfn $"{customer} {total}")ClojureA modern Lisp on the JVM where immutable data is the default.
Rich Hickey designed Clojure as a practical Lisp for the JVM, built around immutable, persistent data structures. It is small, remarkably stable and loved by teams that value simplicity. Nubank, one of the world’s largest digital banks, runs on it.
The big ideaSimple made easy: plain immutable data, pure functions, and a REPL that lets you change a running program.
Strengths
- Immutable data by default makes concurrency far safer.
- REPL-driven development is fast and interactive.
- Exceptionally stable: old code keeps working.
Weaknesses
- Lisp syntax is a barrier for many developers.
- Error messages and stack traces can be cryptic.
- A small hiring pool.
- Reach for it for
- Data-oriented backends, and teams that want simplicity and interactive development.
- Think twice for
- Teams that want static types or a large pool of candidates.
- Created by
- Rich Hickey
- First appeared
- 2007
- Latest
- Clojure 1.12 (1.13 in alpha)
- Typing
- Dynamic, strong; optional spec or Malli for data shapes
- Memory
- Garbage collected; persistent immutable collections
- Runs as
- JVM; ClojureScript for JavaScript, babashka for scripts
- Concurrency
- Atoms, refs (STM), agents, core.async
- Null handling
- nil, treated as an empty collection by most functions
- Paradigms
- Functional, Lisp, Data-oriented
- Packages
- deps.edn, Leiningen · Clojars, Maven Central
- Home turf
Scores
Popularity
- TIOBE
- 51–100
- PYPL
- —
- RedMonk
- —
- IEEE
- #51
- GitHub
- —
- JetBrains
- —
- Stack Overflow
- #40
- Consensus
- #24 of 27
- Admired
- 48.7%
LatelyClojure 1.12 overhauled Java interop, including method values and better support for functional interfaces. The 1.13 alphas add destructuring with required keys.
(def orders
[{:customer "ada" :amount 120 :paid true}
{:customer "grace" :amount 75 :paid true}
{:customer "ada" :amount 30 :paid false}
{:customer "linus" :amount 200 :paid true}
{:customer "grace" :amount 25 :paid true}])
(->> orders
(filter :paid)
(group-by :customer)
(map (fn [[customer os]] [customer (reduce + (map :amount os))]))
(sort-by second >)
(run! (fn [[customer total]] (println customer total))))ElixirErlang’s battle-tested runtime with a friendlier face.
José Valim, then a Rails core team member, built Elixir on the BEAM, the runtime Ericsson created for telephone switches that could not go down. Elixir added friendly syntax, macros and modern tooling, and Phoenix with LiveView made it a strong choice for real-time web apps.
The big ideaLet it crash: millions of isolated processes, watched by supervisors that restart them, so failures stay small and local.
Strengths
- Concurrency and fault tolerance are built into the runtime.
- Phoenix LiveView builds real-time interfaces with little JavaScript.
- Friendly syntax, excellent documentation and tooling.
Weaknesses
- Slower than compiled languages for CPU-bound work.
- A smaller ecosystem and job market.
- Static typing is only now arriving.
- Reach for it for
- Real-time web apps, chat, IoT backends, and systems that must stay up.
- Think twice for
- Number crunching, or teams that need a large hiring pool.
- Created by
- José Valim
- First appeared
- 2012
- Latest
- Elixir 1.20 (June 2026)
- Typing
- Dynamic, strong; since 1.20 the compiler infers and checks types gradually
- Memory
- Garbage collected, per lightweight process
- Runs as
- BEAM (the Erlang VM), with a JIT
- Concurrency
- Millions of isolated processes; supervision trees
- Null handling
- nil; tagged tuples such as {:ok, value} for results
- Paradigms
- Functional, Concurrent, Metaprogramming
- Packages
- Mix · Hex
- Home turf
- Web backends & APIs, Distributed & real-time
Scores
Popularity
- TIOBE
- 51–100
- PYPL
- —
- RedMonk
- —
- IEEE
- #43
- GitHub
- —
- JetBrains
- —
- Stack Overflow
- #32
- Consensus
- #22 of 27
- Admired
- 62.1%
LatelyElixir 1.20’s compiler infers types and gradually type-checks every program, using set-theoretic types, with no annotations required.
orders = [
%{customer: "ada", amount: 120, paid: true},
%{customer: "grace", amount: 75, paid: true},
%{customer: "ada", amount: 30, paid: false},
%{customer: "linus", amount: 200, paid: true},
%{customer: "grace", amount: 25, paid: true}
]
orders
|> Enum.filter(& &1.paid)
|> Enum.group_by(& &1.customer, & &1.amount)
|> Enum.map(fn {customer, amounts} -> {customer, Enum.sum(amounts)} end)
|> Enum.sort_by(fn {_customer, total} -> total end, :desc)
|> Enum.each(fn {customer, total} -> IO.puts("#{customer} #{total}") end)GleamA small, friendly, type-safe language for the Erlang VM and JavaScript.
Gleam, created by Louis Pilfold, brings a small, statically typed functional language to the Erlang VM, and can also compile to JavaScript. It reached 1.0 in March 2024 and has grown quickly from a tiny base, helped by famously friendly error messages and tooling.
The big ideaSimplicity and safety: no null, no exceptions, no macros, one obvious way to do things, on a runtime built for concurrency.
Strengths
- Sound static types with full inference.
- Batteries-included tooling in a single binary.
- Runs on the BEAM or in the browser.
Weaknesses
- Young: a small ecosystem and almost no jobs.
- Deliberately minimal, so some patterns take more code.
- Integration with Erlang’s OTP is still maturing.
- Reach for it for
- Typed services on the BEAM, and developers curious about functional programming.
- Think twice for
- Projects that need many mature libraries, or easy hiring.
- Created by
- Louis Pilfold
- First appeared
- 2016
- Latest
- Gleam 1.19 (October 2026)
- Typing
- Static, strong, inferred (Hindley–Milner)
- Memory
- Garbage collected (by the BEAM or the JavaScript engine)
- Runs as
- Compiles to Erlang for the BEAM, or to JavaScript
- Concurrency
- BEAM processes and OTP, with typed messages
- Null handling
- No null: Option and Result
- Paradigms
- Functional, Concurrent
- Packages
- gleam CLI · Hex
- Home turf
Scores
Popularity
- TIOBE
- —
- PYPL
- —
- RedMonk
- —
- IEEE
- —
- GitHub
- —
- JetBrains
- —
- Stack Overflow
- #41
- Consensus
- #26 of 27
- Admired
- 52.3%
LatelyGleam 1.19 compiles to Erlang abstract forms instead of Erlang source, for faster builds and accurate stack traces.
import gleam/dict
import gleam/int
import gleam/io
import gleam/list
import gleam/option.{None, Some}
pub type Order {
Order(customer: String, amount: Int, paid: Bool)
}
pub fn main() {
let orders = [
Order("ada", 120, True),
Order("grace", 75, True),
Order("ada", 30, False),
Order("linus", 200, True),
Order("grace", 25, True),
]
orders
|> list.filter(fn(order) { order.paid })
|> list.fold(dict.new(), fn(totals, order) {
dict.upsert(totals, order.customer, fn(current) {
case current {
Some(total) -> total + order.amount
None -> order.amount
}
})
})
|> dict.to_list
|> list.sort(fn(a, b) { int.compare(b.1, a.1) })
|> list.each(fn(pair) { io.println(pair.0 <> " " <> int.to_string(pair.1)) })
}11 · Method & sources
How this was put together
Choosing the twenty-seven
The list starts with the general-purpose languages that rank highest on average across the seven popularity sources, then adds smaller languages that developers rate far above their usage: Elixir, Erlang, Gleam, Zig, Odin, Clojure, F#, Haskell, OCaml and Julia. SQL, HTML and CSS, Bash and PowerShell rank near the top of every survey but are left out because you don’t build a whole system in them. SQL deserves a special mention: it is older than all but one language here and will probably outlive most of them. Near misses include Objective-C, Perl, MATLAB and Visual Basic.
The eleven facets
Every facet is scored from 1 to 10. The scores are editorial: mine, calibrated against benchmarks, studies, and how each language behaves on real projects. They compare languages with each other, so a 5 is middling within this group, not bad in absolute terms.
- Performance
- The Computer Language Benchmarks Game, Pereira et al.’s energy-efficiency study, and the runtime model (AOT, JIT, or interpreter).
- Safety
- Memory safety, null safety, soundness of the type system, and protection against data races, weighted in that order.
- Approachability
- Size of the language, number of concepts needed for a first useful program, quality of error messages and learning material.
- Expressiveness
- Abstraction mechanisms (generics, type classes, macros, pattern matching, higher-order functions) and how concise idiomatic code is.
- Concurrency
- The concurrency model, how safe it is by default, and whether it scales across cores without heroics.
- Ecosystem
- Breadth and maturity of packages and frameworks, including access to a host platform such as the JVM, .NET, or C libraries.
- Tooling
- Official build tool, package manager, formatter, test runner, language server, and debugger, and how well they fit together.
- Reach
- Practical targets: servers, browsers, iOS, Android, desktops, microcontrollers, WebAssembly, and embedding in other programs.
- Stability
- Backward-compatibility record, release discipline, governance, and how disruptive recent migrations were.
- Jobs
- IEEE Spectrum’s jobs ranking and job-board volume, adjusted for how often the language is the main skill rather than a side requirement.
- Momentum
- Change over the last three years across TIOBE, PYPL, RedMonk, GitHub contributor counts, and developer surveys.
Popularity
The popularity rank is not a survey. For each source, every language gets its position among these twenty-seven. Languages a source doesn’t rank share the remaining places, and ties share a place. The consensus is the average of those seven positions, and the popularity lens rescales it to 1–10.
- TIOBE Index (Oct 2026): Search-engine results for “<language> programming”.
- PYPL PopularitY of Programming Language (Oct 2026): Share of Google searches for “<language> tutorial”.
- RedMonk Programming Language Rankings (Jan 2026): GitHub pull requests plotted against Stack Overflow tags.
- IEEE Spectrum Top Programming Languages (2025): Seven weighted signals, from search and discussion to research papers and code.
- GitHub Octoverse (2025): Monthly active contributors on GitHub. Only the top ten are published.
- JetBrains State of Developer Ecosystem (2025): Share of 24,534 developers who used the language in the past year.
- Stack Overflow Developer Survey (2026): Share of respondents who did extensive work in the language in the past year.
Some caveats. IEEE Spectrum’s 2026 ranking and JetBrains’ 2026 report weren’t out when this was written, so their 2025 editions are used. PYPL’s Python share jumped by 24 points in a year, which more likely reflects collapsing tutorial searches for everything else than a surge in Python. TIOBE changed its method in October 2026 to include Mandarin search terms, which probably explains sudden jumps for Julia, Dart and OCaml. GitHub ranks by contributors rather than code, and JetBrains’ audience leans towards users of JetBrains tools. That is the point of using seven sources: their biases point in different directions.
Admiration
“Admired” is the share of a language’s current users who want to keep using it, from the 2026 Stack Overflow survey. It is the only large survey that asks this for every language. Its respondents skew towards web developers, and small languages benefit from self-selection, so it is shown as its own lens and never mixed into the popularity rank.
The shared program
Every profile includes the same task written idiomatically: total the paid orders per customer, then print customers from the highest total to the lowest. Thirteen of the twenty-seven were run successfully (C, C++, C#, Erlang/OTP 26, F#, Java, JavaScript, OCaml 4.14, Odin, Python, Rust, TypeScript and Zig 0.17). The rest were written against current documentation and checked by hand. If you spot a mistake, I’d like to hear about it.
Other sources
- Pereira et al., Energy Efficiency across Programming Languages (SLE 2017), for relative speed and energy use.
- Microsoft Security Response Center, We need a safer systems programming language (2019), and the Chromium memory safety page.
- Google Security, Eliminating memory safety vulnerabilities at the source (2024) and Rust in Android (2025).
- The White House ONCD, Back to the Building Blocks (2024), and CISA, Product Security Bad Practices (2025).
- Microsoft, A 10x faster TypeScript (2025).
- Mündler et al., Type-Constrained Code Generation with Language Models (PLDI 2025).
- Cassano et al., MultiPL-E (2022) and MultiPL-T (2023), on language models and less common languages.
- DevJobsScanner, for job postings by language in 2025.
- OCaml releases and Erlang/OTP 29 release notes.
Data as of October 12, 2026. Languages move quickly, and so will some of these numbers. Disagree with a score? Good. The useful part of a spectrum like this is the argument it starts about which trade-offs matter for the system in front of you.