← LOGBOOK LOG-443
EXPLORING · SOFTWARE ·
PROGRAMMING-LANGUAGESHISTORYCOMPILERSSOFTWARE

History of Programming Languages

Programming languages moved from machine-specific instructions toward portable abstractions for data, control flow, objects, functions, and concurrent systems.

Programming languages are layers between human intent and machine instructions. Each major language family changed what could be expressed conveniently: numerical formulas, business records, structured control flow, systems code, objects, functions, or programs spread across a network.

problem → source language → compiler or interpreter → machine instructions

The hardware became faster and more varied. Languages made programs easier to write, reuse, reason about, and move between machines.

Machine Code and Assembly

Early computers were programmed in numeric machine instructions. The programmer had to know the operation codes, register layout, memory addresses, and the exact machine being used.

LOAD  R1, 1000
ADD   R1, 1001
STORE R1, 1002

Assembly language replaced raw instruction numbers with names such as LOAD and ADD, but it still described the machine directly. A program written for one architecture generally could not run on another. Assemblers removed some clerical work; they did not remove the need to think in registers and memory addresses.

FORTRAN and COBOL — Programs for a Job

FORTRAN, released commercially in 1957, was built for scientific and engineering calculation. It let programmers write arithmetic formulas in notation close to the mathematics.

AREA = PI * RADIUS ** 2

The important breakthrough was trust in compilation. A compiler had to produce machine code efficient enough that scientists would use it instead of hand-written assembly.

COBOL came from a different need: business data processing. Records, reports, files, and transactions mattered more than numerical formulas. Its verbose English-like form made programs readable to people working with payroll, inventory, and accounting systems.

ADD AMOUNT TO TOTAL

FORTRAN and COBOL showed that a language could be designed around a domain instead of around an instruction set. That idea remains in SQL, MATLAB, R, Verilog, and many modern domain-specific languages.

ALGOL — Describing Algorithms Clearly

ALGOL 60 introduced a more disciplined way to describe algorithms. Block structure created local scope. Nested expressions, recursive procedures, and begin/end blocks made larger programs easier to organise.

begin
  integer sum;
  sum := 0;
  for i := 1 step 1 until 10 do
    sum := sum + i
end

ALGOL was more influential in language design than in commercial deployment. Its formal report used Backus–Naur form to define syntax precisely. The descendants of its block structure and grammar notation appear in Pascal, C, Java, JavaScript, and most compiler textbooks.

Lisp — Programs as Symbolic Data

Lisp arrived in 1960 from AI research rather than numerical or business programming. Its central structure was the list. Code and data shared the same representation, which made recursive symbolic programs natural.

(define (first-item items)
  (car items))

Functions could be stored in values, passed to other functions, and returned from them. Garbage collection reclaimed unused list structures. Lisp established a different family of ideas from the FORTRAN–ALGOL line: functional programming, metaprogramming, interactive development, and symbolic computation.

Simula and Smalltalk — Objects and Messages

Simula, developed for simulation, introduced classes and objects as a way to model separate entities with their own state and behaviour. Smalltalk later made the object model central: computation happened by sending messages between objects.

account deposit: 100.
account balance.

Objects bundled data with the operations that could change it. This helped manage large programs where data had to remain consistent across many parts of a system. The model shaped C++, Objective-C, Java, C#, Ruby, and much of application programming.

C and Unix — A Portable Systems Layer

C emerged at Bell Labs between 1969 and 1973 alongside Unix. It was close enough to the machine for operating-system work, but high-level enough that Unix could be moved to different hardware with far less rewriting than an assembly-language system.

int sum(int a, int b) {
  return a + b;
}

C exposed pointers, manual memory management, and predictable low-level operations. Those features gave systems programmers control, but they also made memory safety the programmer’s responsibility. C’s syntax and model strongly influenced C++, Java, JavaScript, Go, Rust, and many other languages.

C++, Java, and Managed Runtimes

C++ extended C with classes, stronger abstraction tools, templates, and automatic object lifetime through RAII. It kept C’s performance-oriented systems model while trying to support larger software designs.

Java took another route in the 1990s. It compiled to bytecode for a virtual machine, used garbage collection, and made a common runtime part of the language platform.

class Greeting {
  static void main(String[] args) {
    System.out.println("hello");
  }
}

The virtual-machine model reduced dependence on a specific processor and operating system. Java’s type system and managed memory made many memory errors less likely, at the cost of giving up direct control over allocation and runtime behaviour.

Scripting, the Web, and Multiparadigm Languages

Python, JavaScript, Ruby, and PHP made programming quicker to start. Dynamic types, automatic memory management, compact syntax, and rich standard libraries suited automation, web applications, and fast iteration.

const activeNames = users
  .filter(user => user.active)
  .map(user => user.name)

These languages also mixed ideas from earlier families. JavaScript has objects, functions as values, prototype-based inheritance, and an event loop. Python supports objects, imperative code, generators, and functional operations. Modern languages rarely belong to one paradigm.

The Current Shape

Programming-language history is not a clean replacement sequence. Older languages remain where their constraints still matter: FORTRAN in scientific computing, COBOL in long-lived business systems, C in kernels and embedded systems, Lisp in research and language experimentation.

Newer languages usually combine old ideas with better tooling. Rust combines C-like systems access with ownership-based memory safety. TypeScript adds static checks to JavaScript. Kotlin, Swift, and Scala combine object-oriented programming with functional features. The recurring problem is the same: give programmers stronger ways to describe intent without hiding the parts of the machine that still matter.

Sources