QIAOPANG.COM · SELECTED ESSAYS (2013–2026) · 260 ESSAYSBrowse Chronologically (2013 → 2026) ↗
QiaoPang · Programmers LifeSelected Essays · Systems, Craft & Agentic Era
Timeline ↗

The Slow Evolution of Programming Languages: The Paradox of Language Evolution from the 1960s to the AI Era

The Slow Evolution of Programming Languages: The Paradox of Language Evolution from the 1960s to the AI Era

From the side, a ridge; from the front, a peak; Far and near, high and low, it never looks the same. I cannot know Mount Lu’s true face, For I am myself inside the mountain. — Su Shi, “Written on the Wall of Xilin Temple”

Standing inside the evolution of programming languages, we are often distracted by the shiny new features on the surface and lose sight of the historical lineage. True insight requires stepping outside the present perspective and examining the nature of languages in the light of history. What we call innovation is often the rediscovery of the past; what we call progress is often a slow advance along an established track.

There is a curious phenomenon: the tech world talks endlessly about the AI revolution, quantum computing, and the metaverse, yet look at the programming languages people use every day—the top ten are basically ‘antiques’ from the last century. Why?

I recently watched Kevlin Henney’s GOTO 2024 talk, “Programming Languages: Past, Present, and Future” (https://www.youtube.com/watch?v=0y7IFUYUTgg), in which he uses data and history to give us the answer. More pointedly, he argues that the AI era will not replace programming languages wholesale; it will make the old ones even more deeply entrenched.

Let’s start with a simple fact that many overlook: programming languages are not a detail; they are the foundation of everything.

Programming Languages: The ‘Gravity’ of the Software World

Kevlin offers a lovely analogy: NASA’s 160-meter-tall rocket assembly building looks magnificent, but its shape is entirely determined by two invisible things—materials and gravity. Change either one and the whole building has to be redesigned.

Programming languages are the ‘gravity’ of the software world. They are everywhere, shaping how you think about problems, how you design systems, and even how teams collaborate. Don’t believe it? Ask your team to switch languages tomorrow—it is not merely swapping a tool. The entire tech stack, habits of thought, and development process must be rebuilt from the ground up.

As Kevlin puts it: ‘If programming languages really didn’t matter, why don’t you switch to another one tomorrow?’

The Weight of History: The Language Revolution of the 1960s

Let us return to the 1960s—a decade that seems remote yet casts a long shadow.

The Slow Evolution of Programming Languages: The Paradox of Language Evolution from the 1960s to the AI Era — Architecture Diagram

ALGOL 68: The Forgotten Giant

You may never have heard of ALGOL 68, let alone written code in it. But here’s the interesting part: the keywords you type every day—int, char, void, struct, union—all come from this language. Before it, programming languages dutifully used full words: integer, character, boolean.

ALGOL 68 didn’t just shorten keywords; it pioneered an expression-oriented style of programming. There is no return statement; everything is an expression. Functional programming languages later took this idea and ran with it.

The Invention of if-else: A Seemingly Simple Innovation

It sounds a bit absurd, but if-else really did have to be ‘invented.’ In English everyone says ‘if something, otherwise’; who would say ‘if something, else’? The early programming-language pioneers agonized over this for quite a while:

  • Grace Hopper used OTHERWISE in FLOW-MATIC
  • John McCarthy, in his early design of Lisp, also found otherwise more natural
  • The ALGOL 58 proposal even included odd options like or if and if either

It was not until 1960 that the ALGOL 60 committee settled on else. Klaus Samelson was the key figure; moved by McCarthy’s idea, he championed this concise keyword.

Coroutines: A ‘New’ Concept from 60 Years Ago

Today’s programmers get excited about async/await, goroutines, and coroutines, but did you know that the concept of coroutines dates back to 1958? Yes, 1958—when many readers’ parents may not even have been born.

Melvin Conway—yes, the very man behind Conway’s Law—came up with the concept of coroutines in 1958. Donald Knuth studied it in depth in the early 1960s: ‘The relationship between a main program and a subroutine is that of boss and subordinate, but coroutines are complete equals.’

// Coroutine style in modern Rust
async fn fibonacci_generator() -> impl Stream<Item = u64> {
    let (mut a, mut b) = (0, 1);
    stream! {
        loop {
            yield a;  // The yield concept from the 1970s
            (a, b) = (b, a + b);  // Multiple assignment from 1963
        }
    }
}

Barbara Liskov created the CLU language in the 1970s, and its iterators used the yield keyword directly. Today’s generators and iterators in Python, JavaScript, and C# are, frankly, reinventing a wheel from half a century ago.

Astonishing Stability: Languages, Too, Can Be Frozen in Time

Take a look at the programming-language rankings from September 2024; the data is quite interesting:

The Slow Evolution of Programming Languages: The Paradox of Language Evolution from the 1960s to the AI Era — Architecture Diagram

Combining the top 20 from the three major rankings—TIOBE, RedMonk, and IEEE Spectrum—we see:

  • 80% of the languages were created before 2000
  • The top 5 command 55% of the market share
  • The top 10 account for more than 67%

This is a classic power-law distribution—a pattern found everywhere in social structures. Even more interesting is the view by decade:

The Slow Evolution of Programming Languages: The Paradox of Language Evolution from the 1960s to the AI Era — Architecture Diagram

That big ‘millennial’ pie slice is fixed right there, an enduring summit in the history of programming languages. What does it mean? Most fresh graduates are using programming languages older than they are.

Social Forces Over Technical Merit: The Real Secret to a Language’s Success

Think again about this question: why do some languages stay popular? The answer may disappoint technical fundamentalists: whether a programming language succeeds depends mainly on social factors; technical brilliance is secondary.

Java: ‘Boring’ Is a Feature

In one conversation, someone remarked that ‘Java is quite an interesting language,’ and Kevlin shot back: “No, no, no—it’s boring.” But interestingly, that is precisely why Java succeeded.

From its birth in 1995, Java was never an ‘interesting’ language. It had no revolutionary concepts, its syntax was hardly elegant, and lambda expressions did not arrive until 2014 (later than in C++). Yet this very ‘boringness’—stability, predictability, backward compatibility—made it a favorite of enterprises.

The Convergence Effect in Language Evolution

Look at updates to mainstream languages in recent years and you’ll notice something interesting: everyone is running in the same direction. Almost every mainstream language is adding these features:

  • Lambda expressions and closures
  • Pattern matching
  • Type inference
  • Asynchronous programming support
  • Functional-programming features
// Pattern matching and type inference in Rust
let result = match value {
    Some(x) if x > 0 => x * 2,
    Some(x) => x,
    None => 0,
};

// Functional-style collection operations
let evens: Vec<i32> = (0..100)
    .filter(|x| x % 2 == 0)
    .collect();

John Backus saw it in 1977: ‘Every new language copies all the features of its predecessors, then adds a few new twists.’ Only now we are not building new languages; we keep stuffing new features into old ones.

The Paradox of Functional Programming: Always Tomorrow

In 1977, when John Backus received the Turing Award, he asked: ‘Can programming be liberated from the von Neumann style?’ He said functional programming was the answer.

Forty-seven years later, let’s look at how functional programming languages perform on the rankings:

How many purely functional languages are in the top 20 of the three major rankings? Zero.

That’s right, not one. Haskell didn’t make it; Clojure didn’t make it; F# didn’t make it. Even old Lisp—which occasionally sneaks into the top 30—ranks higher than Clojure.

But this does not mean functional programming failed. On the contrary, its ideas have permeated almost every mainstream language. It is like tai chi: few people practice pure tai chi, but its principles—overcoming hardness with softness, borrowing force, balancing yin and yang—have been borrowed by all sorts of modern martial arts and fitness methods. These languages are not functional; they have simply stolen a bit of functional programming’s ‘internal energy.’

Excel: The Accidental King of Functional Programming

Simon Peyton Jones—the Haskell luminary—once said something that stings: “Excel is the world’s most popular functional programming language.”

Many programmers hate hearing this, because it means the folks in finance may have started ‘functional programming’ before they did. And it makes sense: every Excel cell is a pure function, and the whole spreadsheet is a giant dataflow graph. No side effects, no mutable state—declarative programming through and through.

Even funnier: during the 2020 pandemic, Microsoft engineers, with time on their hands, decided to add lambda-function support to Excel. It was like strapping a rocket booster onto a car that already ran perfectly well—almost nobody uses it, and the effort would have been better spent fixing Excel’s genuinely headache-inducing old flaws.

The AI Era: A Brake on Evolution, Not an Accelerator

This brings us to the most incisive point in Kevlin’s talk: now that AI and large language models are ascendant, they will not accelerate the evolution of programming languages (for human use); they will become a powerful conservative force.

The Statistical Bias of LLMs

The Slow Evolution of Programming Languages: The Paradox of Language Evolution from the 1960s to the AI Era — Architecture Diagram

Large language models are conservative by nature, for a simple reason:

  1. Training data skews old: there is far more old code than new code, and far more examples of old versions than new ones
  2. Popular means more accurate: the more popular a language is, the more data there is and the more reliable the AI’s suggestions are
  3. Feedback loop: AI recommends mainstream approaches → more people use them → more data is generated → AI prefers recommending them even more

Ask AI to write code for you, and it will most likely give you:

  • Code written with older language features
  • Conservative, conventional implementations
  • ‘Safe’ solutions based on a large body of historical examples

When it encounters a niche language or a new feature, the AI immediately falters and its error rate shoots up. This creates a vicious cycle: the strong get stronger, and innovation becomes harder.

A Machine-Learning Algorithm Walks into a Bar

Kevlin tells a wonderfully apt joke:

A machine-learning algorithm walks into a bar. The bartender asks, “What would you like?” The algorithm replies, “What is everyone else drinking?”

This joke perfectly captures the essence of LLMs: they do not create; they perform pattern matching and recombination according to statistical regularities. Applied to programming-language choice, this means:

  • Languages that already dominate will continue to dominate
  • New languages face a higher barrier to entry
  • Innovation will occur mainly at the level of syntactic sugar and tooling, not fundamental change

The Future Is Here; It’s Just Not Evenly Distributed

William Gibson’s famous line—‘The future is already here; it’s just not evenly distributed’—has a special meaning in programming languages. Much of what we take to be ‘innovation’ is simply the rediscovery of the past:

Reinventing the Wheel

‘Modern’ Feature Actual Year of Birth First Appearance
Coroutines 1958 Melvin Conway
Block structure 1960 ALGOL 60
Multiple assignment 1963 CPL
Iterators/yield 1974 CLU (Barbara Liskov)
Pipes 1964 Doug McIlroy
Pattern matching 1973 ML
Optional semicolons 1970s CLU
Lambdas 1936 Alonzo Church

We are not inventing the future; we are slowly reimplementing the past. Every generation of programmers ‘discovers’ these concepts, much as Columbus ‘discovered’ the Americas.

Why Is Evolution So Slow?

// Factors resisting the evolution of programming languages
enum EvolutionResistance {
    LegacyCodebase {
        lines_of_code: u64,  // Billions of lines of legacy code
        migration_cost: Cost, // Astronomical migration costs
    },
    HumanFactors {
        learning_curve: Duration,     // Time cost of learning a new language
        team_coordination: Complexity, // Complexity of team coordination
        mental_models: Inertia,       // Inertia of mental models
    },
    EcosystemLock {
        libraries: Vec<Dependency>,   // Massive ecosystem dependencies
        tools: Vec<Tool>,            // Toolchain lock-in
        platforms: Vec<Platform>,     // Platform compatibility
    },
    SocialDynamics {
        network_effects: Strength,    // Network effects
        job_market: Demand,          // Job-market demand
        community_size: usize,        // Community size
    },
}

The evolution of programming languages faces multiple forms of resistance:

  1. The gravity of legacy systems: billions of lines of COBOL worldwide still run critical financial systems
  2. Ecosystem lock-in: a language’s value lies not in the language itself but in its ecosystem
  3. Cognitive inertia: changing mental models is far harder than learning new syntax
  4. Network effects: the more users a language has, the more valuable it becomes and the harder it is to replace

Deep Reflection: What Is the Essence of Programming?

In this era of AI-assisted programming, Kevlin’s talk prompts us to consider a fundamental question: What is the essence of programming?

Language as a Tool for Thought

Programming languages are not only tools for talking to computers; they are frameworks for thinking about problems. The Sapir-Whorf hypothesis holds that language shapes thought. In programming, this hypothesis has concrete manifestations:

  • C programmers tend to think in terms of memory layout and pointers
  • Lisp programmers naturally think of recursion and list processing
  • Haskell programmers build mental models out of types and pure functions
  • Rust programmers focus on zero-cost abstractions and concurrency safety
  • Go programmers think about concurrency with channels and goroutines

The Value of Simplicity

In his Turing Award lecture ‘The Emperor’s Old Clothes,’ Tony Hoare said: ‘There are two ways of constructing a software design: one way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies.’

The trajectory of modern programming languages seems to favor the latter. The C++ standard has grown thick enough to ‘have its own gravitational field’; JavaScript adds new features every year; even Python, once prized for its simplicity, is becoming increasingly complex.

But truly lasting innovation often comes from simplification rather than complication:

// The power of simplicity: the Unix pipe philosophy
// Each program does one thing, but does it supremely well
fn word_frequency(text: &str) -> HashMap<String, usize> {
    text.split_whitespace()
        .map(|word| word.to_lowercase())
        .fold(HashMap::new(), |mut acc, word| {
            *acc.entry(word).or_insert(0) += 1;
            acc
        })
}

The Programming Paradigm of the Future?

If the past 60 years of programming-language evolution teach us anything, it is this: true paradigm shifts are extremely rare.

We are still using:

  • Control structures from the 1960s
  • Abstraction mechanisms from the 1970s
  • Object models from the 1980s
  • Generic programming from the 1990s

Even seemingly revolutionary innovations—reactive programming, functional reactive programming, the Actor model, and so on—can be traced back decades.

Practical Lessons: How to Make Wise Choices in an Era of Slow Evolution

1. Choose Boring Technology

‘Choose Boring Technology’ is not conservatism; it is wisdom. Boring means:

  • Stable language specifications
  • Mature ecosystems
  • Abundant learning resources
  • A predictable future

2. Depth Over Breadth

Rather than chasing every new language and framework, understand a few of them deeply:

// Understanding the memory model deeply is more valuable than learning the syntax of ten languages
use std::rc::Rc;
use std::cell::RefCell;

// Understanding why Rc<RefCell<T>> is needed
// matters more than knowing the smart-pointer syntax of ten languages
type SharedMutable<T> = Rc<RefCell<T>>;

3. Principles Over Features

Understanding the principles behind programming languages matters more than mastering specific features:

  • Understand the essence of closures, not just their syntax
  • Understand type-system theory, not just usage
  • Understand the trade-offs of concurrency models, not just APIs

4. Embrace the ‘Good Enough’ Philosophy

Perfect is the enemy of good. In choosing a programming language:

  • A good-enough language + excellent design > a perfect language + terrible design
  • A language the team knows > a theoretically better language
  • A language with an active community > a technically superior but niche language

Conclusion: Soaring Within a Gravitational Field

Returning to Kevlin’s metaphor: programming languages are like gravity—everywhere, shaping everything, yet often overlooked. We cannot escape gravity, but we can learn to soar gracefully within it.

The evolution of programming languages may never be as fast as we hope, and the intervention of AI may make the process even more conservative. But that is not necessarily bad. Stability brings predictability, conservatism ensures compatibility, and slow evolution gives us time to truly understand and master our tools.

As Bjarne Stroustrup said: ‘There are only two kinds of programming languages: the ones people complain about and the ones nobody uses.’ The languages we use are all imperfect, but they are good enough, stable enough, and powerful enough to let us build software that changes the world.

In this new era of AI-assisted programming, understanding the history, present state, and future trends of programming languages is more important than ever. Not because we need to predict the next ‘great language,’ but because we need to understand: true innovation lies not in the language itself, but in how we use it to express ideas, solve problems, and create value.

The programming languages of the future may not change in revolutionary ways, but the programmers of the future—those who know history, understand principles, embrace simplicity, and pursue essence—will create a true revolution.

“The past is never dead. It’s not even past.” — William Faulkner

In the world of programming languages, this sentence carries special meaning: what we take to be innovation is often the rediscovery of the past; the future we await may already be waiting in some dusty paper; and the tools we use every day embody more than half a century of accumulated wisdom. Understanding this may be the first step toward becoming a better programmer.

MORE IN Languages & Craft

Further Reading in This Column

View all essays in “Languages & Craft” →

Time to Meet jj: Git's Next Evolutionary Step

Git has ruled version control for twenty years, but its staging area, brittle rebases, and blocking merge conflicts are becoming liabilities in the AI era. jj rebuilds the mental model from the ground up — while staying fully Git-compatible. Here's why it deserves your attention.

New Hope (2025–2026)5,588 chars · 12 min read