The Evolution of Programming Languages How We Learned to Talk to Computers

From Sebastian Gerstl | Translated by AI 9 min Reading Time

Rust, Python, and C are now part of a computer programmer's standard repertoire. But it has been a long journey from directly feeding binary instructions into system registers to modern vibe coding.

The Evolution of Coding: In the past, programs were written by hand and fed into the computer using punch cards and switches. Today, in the age of “vibe coding,” computers can largely program themselves.(Image: Dall-E / AI-generated)
The Evolution of Coding: In the past, programs were written by hand and fed into the computer using punch cards and switches. Today, in the age of “vibe coding,” computers can largely program themselves.
(Image: Dall-E / AI-generated)

As early as 1843, Ada Lovelace described a procedure for calculating Bernoulli numbers for Charles Babbage’s Analytical Engine, which was never completed. This is generally considered the first computer program. Even though Lovelace was able to explain to a reader how such a program might be structured, one question remained largely unanswered due to the lack of a finished computer: How can we “talk” to the computer so that it understands how to carry out our instructions? And how can we do this in a way that remains as natural and comprehensible as possible for humans? When the first electronic general-purpose computers emerged about a century later, this idea could initially be implemented only to a limited extent.

Back When Programming Still Meant Modifying the Computer

When the ENIAC was completed in 1945, there was initially no program that could simply be loaded from memory. To perform new calculations, cables had to be reconnected and switches and function tables had to be adjusted. The six women who were among its first programmers—Kay McNulty, Betty Jennings, Betty Snyder, Marlyn Wescoff, Fran Bilas, and Ruth Lichterman—were initially provided with neither a programming language nor comprehensive training. They familiarized themselves with the machine using circuit diagrams and block diagrams and then translated their procedures into hundreds of plug connections and thousands of switches.

It was no coincidence that women played a central role in this early phase. “Computer” had previously been a job title: Hundreds of mostly female mathematical assistants calculated things like ballistic tables using mechanical calculators. Some of these “human computers” went on to become programmers of electronic computers. At first, software was viewed less as prestigious engineering work and more as a continuation of mathematical calculation work.

With the stored-program principle, instructions could finally be stored in memory themselves. At first, however, programming was done in machine code: sequences of numbers that corresponded directly to a computer’s architecture. One of the first responses to this came, once again, from a woman. Kathleen Hylda Valerie Britten, later Kathleen Booth, began working on early computers at Birkbeck College in 1946. In 1947, she developed a symbolic coding system for the ARC with Andrew Booth and was involved in the development of the assembler and Autocode for the Birkbeck computers. Her work is often described as one of the first—and in some cases, the very first—assembler languages; however, due to systems that emerged at the same time, the question of priority is not entirely clear. Instead of numerical operation codes, symbolic abbreviations and addresses could now be used: The programmer still had to understand the machine, but no longer had to think exclusively in terms of numbers.

FORTRAN, COBOL, and BASIC: Common Languages for Machines and Users

The next leap forward was to move away from the computer’s specific instruction set. One of the driving forces behind this was Grace Hopper. In 1952, she developed A-0, an early compiler system for the UNIVAC; MATH-MATIC and FLOW-MATIC followed later. The latter described business processes in a form more closely oriented toward English and had a significant influence on the COBOL language, which was developed starting in 1959. Hopper was not its sole inventor—COBOL was developed by the CODASYL committee—but her fundamental idea proved formative: People describe the problem in an understandable way, and the computer handles the translation.

At almost the same time, John Backus at IBM developed FORTRAN (“Formula Translation”) for scientific and technical calculations. When the language was released for the IBM 704 in 1957, its optimizing compiler was the key to its success. Many programmers doubted that automatically generated code could compete with hand-written assembly language. However, the FORTRAN team produced code whose efficiency was close to that of hand-optimized programs—thereby establishing the high-level language as a serious economic contender.

From then on, languages were developed for different users and ways of thinking. FORTRAN shaped science and technology, while COBOL shaped business and administrative software. John McCarthy’s LISP took a different path in 1958: programs and data could be treated as lists, and recursion and symbolic processing took center stage—an early root of functional programming.

Subscribe to the newsletter now

Don't Miss out on Our Best Content

By clicking on „Subscribe to Newsletter“ I agree to the processing and use of my data according to the consent form (please expand for details) and accept the Terms of Use. For more information, please see our Privacy Policy. The consent declaration relates, among other things, to the sending of editorial newsletters by email and to data matching for marketing purposes with selected advertising partners (e.g., LinkedIn, Google, Meta)

Unfold for details of your consent

In 1964, two very different approaches emerged. John Kemeny and Thomas Kurtz developed BASIC at Dartmouth College to make programming accessible to students and non-specialists. Combined with time-sharing, programming became more interactive; a decade later, BASIC was a perfect fit for the home computer revolution. On the Altair 8800, input in the basic version was still done via DIP switches, but even a contemporary article highlighted the advantages of assembler, FORTRAN, and BASIC over machine code. Bill Gates, Paul Allen, and Monte Davidoff ultimately turned Altair BASIC into an early commercially significant software product for microcomputers in 1975.

IBM’s PL/I took an almost opposite approach: Developed in the mid-1960s, the language was intended to handle scientific FORTRAN tasks as well as COBOL-style business processing, while also offering block structure, recursion, exceptions, and multitasking. The ambition was nearly universal—and correspondingly complex. Even then, a conflict emerged that remains relevant to this day: Should a language solve as many tasks as possible, or should it remain as simple as possible for a specific purpose?

From the "Tower of Babel" of Programming Languages to Structured Programming

In the 1960s and 1970s, the hierarchy of “low-level” to “high-level” languages finally evolved into a family tree. ALGOL 60 established a systematic block structure and influenced languages such as Pascal and C. Simula expanded on ALGOL’s ideas by introducing classes and objects and is considered the first language designed for object-oriented programming; Smalltalk made the object the centerpiece of an entire system in the 1970s. Prolog relied on logical rules, while SQL relied on declarative data queries: the programmer focuses more on describing the desired result rather than specifying every computational step.

That said, there were also developments that, in hindsight, turned out to be dead ends. One example is Forth. Charles “Chuck” Moore developed the stack-based language around 1970 based on his work on small computers and control systems. Instead of building increasingly complex high-level languages, Forth relied on a tiny language core, a stack, and the ability to define new “words” from existing ones. In 1971, a complete implementation ran on the National Radio Astronomy Observatory’s 11-meter radio telescope. This radical simplicity was particularly appealing on resource-constrained systems.

As programs grew in size, complexity became a critical problem. Edsger W. Dijkstra was one of the leading advocates of the idea that programming must become a methodical, transparent discipline. His 1968 paper, famous under the editorially assigned title “Go To Statement Considered Harmful,” was directed against uncontrolled jumps in program flow. The goal was broader than simply eliminating a single command: programs should consist of clear control structures whose behavior could be systematically understood.

Structured programming—using sequences, loops, decisions, and procedures—defined languages such as Pascal. Paradoxically, the next major advance then brought programming closer to the hardware again: a language needed to provide enough structure for large programs while remaining efficient enough to be used for writing operating systems.

C and C++: A Breakthrough for Object-Oriented Languages

That language was C. Dennis Ritchie developed it between 1969 and 1973 at Bell Labs, building on the BCPL and B line of languages and closely tied to Ken Thompson’s Unix. C offered data types, functions, and control structures, but also gave programmers a great deal of control through pointers and direct memory access. In 1973, most of Unix was rewritten in C. As a result, operating system software no longer had to be completely rewritten in assembly language for every processor architecture: C combined portability with remarkable hardware proximity.

This balance explains its tremendous longevity. C became the foundation for operating systems, compilers, drivers, and embedded software, and influenced countless successors. However, the claim that it is “dominant today” is only true to a limited extent: Across the entire software landscape, Python, JavaScript, and Java are of enormous importance, while C remains a defining force primarily in system and embedded software. The attached IEEE Spectrum ranking from 2024 even shows a decline for C, while C++ remains strong and Rust is gaining ground.

In the late 1970s, Bjarne Stroustrup wanted to address a weakness in C: large systems could be programmed efficiently, but could only be organized to a limited extent using higher-level abstractions. Stroustrup was familiar with Simula and appreciated its class concept, but was dissatisfied with its runtime efficiency. In 1979, he began working on “C with Classes” at Bell Labs; the name C++ was coined in 1983, and the first commercial version was released in 1985. His goal was to combine data abstraction and object-oriented programming with the efficiency of C.

Object-oriented programming was by no means new, but it became mainstream in the 1980s and, above all, in the 1990s. C++ brought it to system and application software, while Java, starting in 1995, made classes and objects the core of a deliberately portable platform. Instead of compiling directly for a processor, code was compiled for the Java Virtual Machine; garbage collection and standard libraries relieved developers of additional tasks. At the same time, Python, JavaScript, PHP, and Ruby emerged. With the rise of the web, development time, maintainability, libraries, and rapid deployment often became more important than maximum execution speed.

In the 2000s, therefore, what emerged was less a single new paradigm and more a blending of existing approaches. C#, Java, and later C++ adopted functional concepts; dynamic languages gained powerful runtimes and frameworks. Object-oriented, imperative, functional, and declarative elements could now coexist within the same language. At the same time, concurrency, distributed systems, and stronger type and safety checks took center stage.

Smartphones, the Cloud, and Storage Security: Requirements for Modern Programming Languages

The next wave came in the 2010s with smartphones and tablets. Mobile software had to run on hardware with limited power while also handling touch interfaces, sensors, wireless connections, and large operating system frameworks. Apple introduced Swift in 2014 as a modern alternative to Objective-C. The goal was to combine high performance with type safety and an accessible syntax; Swift has since become the preferred language for Apple platforms. On Android, Kotlin was officially supported in 2017, and in 2019, Google declared its development strategy increasingly “Kotlin-first.” Null safety, concise syntax, and coroutines demonstrate how modern languages aim to prevent common errors through their very design.

The shift is even more evident in Go and Rust. Go was developed at Google starting in 2007, drawing on the experiences of Robert Griesemer, Rob Pike, and Ken Thompson with large codebases, multicore processors, and distributed systems. The language emphasizes simplicity, fast compilation, standardized tools, garbage collection, and lightweight concurrency—and thus, above all, addresses the day-to-day challenges faced by large software teams.

Rust addresses a different vulnerability—and in doing so, takes us back to C. Graydon Hoare’s project was publicly unveiled at Mozilla in 2010 and was intended to combine high speed and hardware control with stronger memory safety. The ownership and borrowing model allows the compiler to check who owns memory and how references are used. The goal is to catch many classic error classes from C and C++ during compilation, without necessarily using a garbage collector.

As a result, the demands placed on programming languages have shifted once again. The early high-level languages freed people from numerical opcodes; FORTRAN made it possible to express mathematical tasks, COBOL made business processes expressible, BASIC made programming accessible, C made system software portable, and C++ made it easier to structure large programs. Modern languages also aim to prevent entire classes of errors and make parallelism and distributed systems manageable.

New languages do not simply replace the old ones. FORTRAN continues to be used in science and high-performance computing, COBOL in decades-old business and banking systems; even Forth, which was removed from the IEEE Spectrum Index in 2024, lives on in niche applications. At the same time, Python ranks near the top in current rankings, while C and C++ continue to operate beneath many modern software stacks.

Perhaps that is precisely the most important constant in nearly eight decades of programming history: there is no single “best” programming language. Each generation redraws the line between humans and machines. Assembler gave machine instructions names. High-level languages hid the specific processor. Object-oriented programming and modules helped organize increasingly complex programs. Mobile platforms tied the language and ecosystem more closely together, and today Rust shifts parts of error prevention into the type system. The history of programming is thus less a story of how people learned to use computers better—and more about how they got computers to take on more and more of the work of programming themselves. (sg)