§ 01 — Lineage · a field guide, 1943 → 2026

The family tree of programming languages

Every language a knot, every line a descent or an influence. Hover a name to trace its ancestry back to the source; click it to open its era.

The ALGOL lineThe LISP lineThe ML lineThe Objects lineThe websolid = descent · dashed = influence
196019701980199020002010The ALGOL lineThe LISP lineThe ML lineThe Objects lineThe webALGOL 60BCPL ’67B ’69C ’72C++ ’85Java ’95C# ’00LISP ’58Scheme ’75Common Lisp ’84Clojure ’07ML ’73Standard ML ’83Haskell ’90OCaml ’96F# ’05Rust ’15Simula 67Smalltalk-80Objective-C ’84Ruby ’95JavaScript ’95TypeScript ’12

§ 02 — Eras

Seven ages of syntax

Each era answers the same question a different way: how much of the machine should the programmer have to see? Open any language to see the idea it contributed.

The Wired Age

To program was to re-wire. Plugboards, switches and punched tape — one machine, one task, one truth at a time. The word “software” would not appear in print until 1958; the first programmers were inventing the job as they did it.

  • the innovation — the plan

    Zuse planned programs for a machine that no longer existed: assignment, subprograms and structured data — designed on paper in 1945, first executed only in 2000.

    • assignmentValues bind to names with a single arrow, so a program reads as a sequence of plans instead of memory addresses.
    • subprogramsReusable procedures with their own variables — nested, and free to call themselves.
    • structured dataArrays and records: the program can hold collections, not just single numbers.
    • the if-statementConditional branching existed before the hardware it was designed for could run the code.
    the problem it solves
    Programming a binary machine meant re-wiring it by hand. Zuse wanted a notation in which engineers could write computation itself — plans, not plugboards.
    the problem it carries
    It existed only on paper: unpublished, unimplemented, unrun until 2000 — a full language that influenced almost nothing.

    run it today

    Nothing installs — that is the point. The first full Plankalkül program ran in 2000, reconstructed from Zuse’s paper. Rojas et al.’s implementation report is the tour.

    Plankalkül — 101 & 201

    | Zuse's plan notation, 1945
    V0[i] + V1[i]  =>  R1
    R1             =>  V2[i]

    reconstructed — notation of the era, simplified

  • the innovation — the code word

    The first step above the metal: algebra rewritten as code words, walked through the machine by human “computers” — interpretation by hand, automated only later.

    • expression-level inputPrograms are written as algebra — sums, products, powers — not as machine instructions.
    • symbolic variablesSingle-letter names and chosen code words for operators; the machine translated the algebra by hand.
    • human interpretationThe first “compiler” was a room of people: one shift per statement, a proof of concept that stuck.
    the problem it solves
    Machine code was illegible and error-prone. Short Code let mathematicians write ordinary algebra and have it translated for the machine.
    the problem it carries
    Slow — “interpreted” first by human computers, later by machinery; no control over the machine, and no path forward.

    run it today

    Ran on BINAC and UNIVAC I. “Running it today” means reading the 1952 operations manual — the human was part of the interpreter.

    Short Code — 101 & 201

    | equations entered as code words,
    | evaluated by hand against the machine
    X3  <-  X1  (+)  X2

    reconstructed — notation of the era, simplified

  • the innovation — the compile

    Glennie’s compiler turned formulas straight into machine code — no human translation step. The argument of the next seventy years, settled in embryo: describe the math; let the machine do the rest.

    • formula translationAlgebraic expressions compiled straight to machine code, with no assembly step in between.
    • assignment and repetitionVariables and counted loops written directly, in the notation of the paper.
    • hardware intimacyIt knew one machine — Ferranti Mark 1 — down to the memory map, and traded generality for speed.
    the problem it solves
    Translation itself was the bottleneck: every formula became hand-written assembly. Autocode proved the machine could do the translating.
    the problem it carries
    Bound to one machine and nearly no abstraction — a demonstration that something was possible, not a tool that traveled.

    run it today

    Welded to the Manchester Mark 1 / Ferranti. It survives in emulators and museum demonstrations, not toolchains.

    Autocode — 101 & 201

    | formulas in, machine code out
    x1 = 2
    x2 = x1 + 3

    reconstructed — notation of the era, simplified

  • the innovation — the call

    Hopper’s A-0 treated the machine as a library: programs became sequences of subroutine calls. “Nobody believed that,” she said — they thought computers could only do arithmetic.

    • the subroutine libraryEvery operation is a call into a library of hand-written routines; the program becomes a table of calls.
    • symbolic addressingNames resolve to locations automatically, so code can be moved and reused without relabeling.
    • debugging by translationHopper compared the program against its machine trace — the origin of finding bugs by instrumenting the program.
    the problem it solves
    Programmers kept rewriting the same routines by hand. Hopper’s A-0 made a program a list of calls into a library of reusable parts.
    the problem it carries
    Barely a language — closer to a linking scheme — and the establishment didn’t believe it counted as programming at all.

    run it today

    A-0’s routine tapes are archive material. Its descendant, though, is on your machine: every build system is Hopper’s library of calls.

    A-0 — 101 & 201

    | the program is a list of calls
    CALL 63 (x, y, result)

    reconstructed — notation of the era, simplified

The Compiler Age

Let the machine translate. FORTRAN proved a compiler could rival hand-written assembly, and programs became portable. The dreams of this decade — recursion, garbage collection, block structure — still run the world.

  • the innovation — the DO loop

    The DO loop, compiled: FORTRAN’s optimizer proved high-level code could match hand-written assembly — and the punch card’s fixed columns set programming’s ceremony for a decade.

    • the DO loopCounted iteration as a single statement, which the compiler unrolls into straight-line machine code.
    • array arithmeticWhole arrays are operated on at once — A = B + C across thousands of elements in one line.
    • subprograms and librariesFunctions, subroutines and later libraries with explicit interfaces; the model every language since copied.
    • an optimizing compilerThe first production optimizer in the field — proof that high-level code could run at hand-written speed.
    the problem it solves
    Programmers cost more than machines. FORTRAN let scientists write mathematics and get machine-speed code back from a compiler.
    the problem it carries
    Punch-card ceremony: fixed columns, six-character names, and dialects that fragmented for decades afterward.

    run it today

    installbrew install gfortran

    rungfortran fact.f -o fact && ./fact

    FORTRAN — 101 & 201

          SUM = 0.0
          DO 10 I = 1, N
       10 SUM = SUM + A(I)

    FORTRAN, 1957

  • the innovation — the conditional

    The conditional, recursion, garbage collection — and code written as the very data structure it manipulates. Nine ideas for one language; all nine still load-bearing.

    • s-expressionsOne syntax — a parenthesized list — serves as both program and data structure.
    • conditionals and recursionif and cond plus defun make the function the unit of program, and recursion replaces the loop.
    • garbage collectionAllocation and reclamation handled by the runtime; the programmer never frees.
    • homoiconicityCode is data you can build at run time and eval — the root of every macro system since.
    the problem it solves
    Numbers were easy for machines; symbols and recursion were not. LISP was built to compute with ideas — lists, functions, programs.
    the problem it carries
    The parentheses (“lots of irritating superfluous parentheses”), runtime costs that offended the era, and a thousand dialects of the same dream.

    run it today

    installbrew install sbcl

    runsbcl --script fact.lisp

    lineage → Scheme

    LISP — 101 & 201

    (cond ((null xs) 0)
          (t (+ 1 (len (cdr xs)))))

    LISP, 1958

  • the innovation — the record

    Data first: the record — named fields, pictures of their format — so a payroll program could read like the payroll office talks. Verbs for managers, structure for the machine.

    • the recordFixed-layout fields described with PICTURE clauses — data specified before the logic that uses it.
    • english-like verbsMOVE, ADD, DISPLAY: a hundred English words that read like a procedure in a manual.
    • divisionsIdentification, environment, data, procedure — a program organized like a bound document.
    • the portability mandateOne standard enforced across vendors by the DoD — the reason it outlived every rival.
    the problem it solves
    Every vendor’s machine processed business data differently, and programs were unreadable to management. COBOL standardized both.
    the problem it carries
    Verbosity beyond parody — and it worked so well that billions of lines are still running, long after anyone could fully explain how.

    run it today

    installbrew install gnucobol

    runcobc -x fact.cob && ./fact

    COBOL — 101 & 201

    MOVE WAGE TO OLD-WAGE.
    ADD BONUS TO WAGE.
    DISPLAY "NEW WAGE IS" WAGE.

    COBOL, 1959

  • the innovation — the block

    The block: nested scopes, declared names, structure you can prove things about — and a grammar defined in BNF. Every C-family language since is a dialect of this argument.

    • the blockbegin…end scopes names and variables; structure that nests and reasons.
    • lexical scopeA name is visible exactly where it was declared — the ancestor of every block-scoped language.
    • call-by-nameArguments are expressions, re-evaluated at each use — Jensen’s device, and the mother of lazy evaluation.
    • a BNF grammarThe syntax defined in Backus–Naur form, so parsers could be generated mechanically.
    the problem it solves
    Algorithms were published in prose nobody could verify. ALGOL 60 became the universal notation for expressing them precisely.
    the problem it carries
    No standard input/output, no vendor behind it: adopted by every textbook, deployed by almost no computer.

    run it today

    installbrew install marst

    runmarst fact.a -o fact.c && cc fact.c -lmarst -lm -o fact && ./fact

    lineage → BCPL

    ALGOL 60 — 101 & 201

    begin
      integer n;
      n := 5
    end

    ALGOL 60, 1960

The Systems Age

Languages return to the metal. C is invented to rewrite Unix and becomes the substrate of everything. Dijkstra’s 1968 letter makes the goto heresy. Objects and logic appear quietly, in Oslo and Marseille.

  • the innovation — the class

    The class: data and the procedures that own it, bundled and stamped into objects — invented to simulate ships in a Norwegian fjord, ended up simulating everything else.

    • the classData and the procedures that own it, packaged together behind one interface.
    • inheritanceA subclass refines its parent — the first object-oriented inheritance in any language.
    • ref and newReferences separate identity from object, making shared structures and graphs expressible.
    • coroutinesTwo routines that suspend and resume each other — the ancestor of generators, fibers and async/await.
    the problem it solves
    Simulating ships and harbors didn’t fit procedural decomposition. Simula let the program mirror the world: things, with behavior.
    the problem it carries
    Slow, niche, and mainframe-bound — the mainstream would spend a decade ignoring the idea it had handed them.

    run it today

    installbrew install cim

    runcim fact.sim && ./a.out

    lineage → Smalltalk-80 · ⇢ C++

    Simula 67 — 101 & 201

    class Ship (x, y);  real x, y;
    begin ... end;
    
    ref (Ship) s;
    s :- new Ship (0.0, 0.0)

    Simula 67, 1967

  • the innovation — the enforced type

    The enforced type: ranges and records checked before the program ever ran. Wirth built a language small enough to teach and strict enough to trust.

    • strong typingEvery variable has a declared type, and the compiler enforces it on every assignment.
    • subrange and enumerated typesLegal values declared up front — type Hour = 0..23 — so out-of-range data cannot exist.
    • records and arraysStructured data with a fixed layout, plus the standard routines for files and text.
    • a small surfaceA language you can hold in your head — the entire point of the design.
    the problem it solves
    Students learned bad habits from forgiving languages. Pascal made correctness a habit — small, strict, and teachable in one term.
    the problem it carries
    Too strict for systems work: fixed-length arrays, thin I/O, and no real module story once it escaped the classroom.

    run it today

    installbrew install fpc

    runfpc fact.pas && ./fact

    Pascal — 101 & 201

    type Hour = 0 .. 23;
    var  noon : Hour;
    begin
      noon := 12
    end.

    Pascal, 1970

  • the innovation — the struct & pointer

    The struct and the pointer: memory you can see, types light enough to carry. Unix rewritten in C became the first portable operating system — and C became the substrate.

    • pointers and arraysAddresses are first-class values, and arrays are pointers wearing syntax.
    • structs and unionsData laid out exactly as specified, byte for byte — the hardware’s own shapes, named.
    • the preprocessorThe language is extended by text substitution before compilation: macros, includes, conditional code.
    • manual memorymalloc and free — the programmer owns every byte, and pays for it in leaks.
    • undefined behaviourThe standard leaves certain programs meaning anything; the sharp edge that cost the industry decades.
    the problem it solves
    Operating systems were written in assembly that could never move between machines. C made Unix — and portability — possible.
    the problem it carries
    It trusts the programmer absolutely; undefined behavior and buffer overflows became the security industry’s substrate.

    run it today

    runcc fact.c -o fact && ./fact

    lineage ← B · → C++

    C — 101 & 201

    struct ship { char *name; int tons; };
    struct ship s = { "Perch", 24 };
    struct ship *p = &s;
    p->tons += 10;

    C, 1972

  • the innovation — the rule

    The rule: state the relation, ask the question — and the machine searches for its own proof. Logic itself, executable.

    • facts and rulesKnowledge, not procedures: relations stated as facts, and rules over those facts.
    • unificationSolving a goal means matching it against the database, substituting variables as it goes.
    • backtrackingFailure is not an error — the engine simply tries other ways; search is the control flow.
    • lists and recursionA built-in relation over lists makes the language deeply expressive from the first day.
    the problem it solves
    Natural-language questions and theorem-proving didn’t fit control flow. Prolog made logic itself executable: facts, rules, unification.
    the problem it carries
    The engine’s search is opaque, performance is a puzzle, and the fifth-generation hype wrote checks it couldn’t cash.

    run it today

    installbrew install swi-prolog

    runswipl fact.pl

    Prolog — 101 & 201

    mortal(X) :- man(X).
    man(socrates).
    
    ?- mortal(socrates).
       true.

    Prolog, 1972

  • the innovation — the inferred type

    The inferred type: you write the function, the language deduces the type — and refuses the program if the two disagree. Milner’s algorithm made safety silent.

    • type inferenceTypes are deduced rather than declared, and the compiler proves the program well-typed.
    • pattern matchingFunctions are defined by cases on the shape of data; a missing case is reported, not defaulted.
    • polymorphismOne definition serves every type that fits — generics without a single annotation.
    • the value restrictionThe discipline that keeps inference sound once references enter the picture.
    the problem it solves
    Proof tactics had to be correct before they ran. Milner made the compiler derive the types — so errors surfaced before execution.
    the problem it carries
    An academic home and a small ecosystem — for decades, the best language you weren’t allowed to deploy.

    run it today

    installbrew install smlnj

    runsml fact.sml

    lineage → Standard ML · → Haskell

    ML — 101 & 201

    fun map f []      = []
      | map f (x::xs) = f x :: map f xs;
    
    (* val map = fn : ('a -> 'b) -> 'a list -> 'b list *)

    ML, 1973

  • the innovation — the continuation

    The continuation: call/cc hands you the rest of the computation as a value you can call later. LISP reduced to a kernel small enough to verify.

    • a minimal kernelA handful of special forms; everything else is a library built on top of them.
    • proper tail callsRecursion in tail position is a jump, not a stack frame — infinite loops are safe.
    • first-class continuationscall/cc captures the rest of the computation as a value you can store and resume later.
    • lexical closuresScope by nesting, not by rulebooks — the modern Lisp core in four keywords.
    the problem it solves
    LISP had sprawled into dialects with unclear semantics. Scheme reduced it to a kernel small enough to reason about completely.
    the problem it carries
    Minimalism pushes every decision to the library — and the tower of Schemes fragmented the idea all over again.

    run it today

    installbrew install mit-scheme

    runmit-scheme --script fact.scm

    lineage ← LISP · → Common Lisp · ⇢ JavaScript

    Scheme — 101 & 201

    (call/cc
      (lambda (k) (k 42)))
    
    ;=> 42 — the future itself, as a value

    Scheme, 1975

  • the innovation — the query

    The query: describe the result you want — the database finds the path. Declarative computing for the office, and the longest-lived success among all “English-like” languages.

    • declarative queriesYou state the shape of the answer; the planner decides how to find it.
    • the relational modelTables, keys and relations — data described independently of the program that reads it.
    • joinsRelations combine by value rather than by pointer, so unrelated data still lines up.
    • aggregationGROUP BY folds rows into summaries; HAVING and ORDER BY shape the folded result.
    the problem it solves
    Data sat in files nobody but a programmer could interrogate. SQL let the question be asked in something close to English.
    the problem it carries
    You own the question; the optimizer owns the answer. Plus NULL logic that betrays both, and injection for every string-built query.

    run it today

    runsqlite3 < crew.sql

    SQL — 101 & 201

    SELECT name, wage FROM crew
    WHERE wage > 5000
    ORDER BY wage DESC;

    SQL, 1974

Objects Ascendant

The class escapes the lab. Xerox PARC ships Smalltalk and the modern GUI in the same box; Stroustrup bolts classes onto C. Message-passing becomes the decade’s big idea.

  • the innovation — the message

    The message: no operators, no statements — only objects sending words to objects, even to build the IDE itself. The environment is written in the language it describes.

    • uniform messagingEverything is an object, and every interaction is a message — unary, binary or keyword.
    • the browser and workspaceLive editing and inspection of running objects: the IDE as part of the language.
    • blocks as objectsClosures are first-class values, passed to collection methods like collect: and select:.
    • image-based persistenceThe running system is the database; changes take effect instantly, no build step.
    the problem it solves
    Kay wanted computing children could wield — programs as conversations between objects, in an environment you live inside.
    the problem it carries
    Purity has a price: everything-an-object overhead, an image opaque to version control, and licensing that kept it niche.

    run it today

    installbrew install gnu-smalltalk

    rungst fact.st

    lineage ← Simula 67 · → Objective-C · ⇢ Ruby

    Smalltalk-80 — 101 & 201

    #(1 2 3 4 5)
       collect: [ :each | each * each ]

    Smalltalk-80, 1980

  • the innovation — the range type

    The range type: legal values declared up front, violations caught at compile time — a language built so the mistake is impossible to type in.

    • strong types and subtypesTypes are contracts; subtypes narrow them further without new machinery.
    • packagesSpecification separated from implementation, with private parts — code compiled against a promise.
    • tasks and rendezvousConcurrency in the language itself: protected objects and synchronous calls between tasks.
    • run-time checksRange, overflow and discriminant checks by mandate — failure is loud, not silent.
    the problem it solves
    Embedded systems ran on hundreds of incompatible languages. Ada promised one verifiable standard for safety-critical code.
    the problem it carries
    The iron collar: heavy ceremony, expensive tooling, compile-time rigidity — arriving just as the world shipped C.

    run it today

    installGNAT Community — developer.adacore.com

    rungnatmake fact.adb && ./fact

    Ada — 101 & 201

    type Hour    is range 0 .. 23;
    subtype Morning is Hour range 8 .. 12;

    Ada, 1983

  • the innovation — the bracket message

    The bracket message: Smalltalk’s words bolted onto C’s bones — verbose, unmistakable, and the sound of Apple software for thirty years.

    • the messageBracket syntax for any message; the selector is a first-class string you can build at run time.
    • reference countingOwnership by retain and release — manual before ARC, automatic after.
    • categoriesExtend any class, including ones you did not write and cannot change.
    • a dynamic runtimeMessage forwarding, runtime introspection and key-value observing underneath it all.
    the problem it solves
    Objects were proven, but C owned systems software. Objective-C brought messaging to C with a layer thin enough to ship.
    the problem it carries
    Verbose brackets, two type systems in one file, and (for most of its life) memory management by hand.

    run it today

    runclang -framework Foundation fact.m -o fact && ./fact

    lineage ← Smalltalk-80

    Objective-C — 101 & 201

    NSString *s =
      [@"Mac" stringByAppendingString: @"intosh"];

    Objective-C, 1984

  • the innovation — the destructor

    The destructor: cleanup guaranteed at scope exit, resources tied to object lifetime — abstraction that costs zero at runtime. RAII is still C++’s best idea.

    • RAIIResources released when objects die — deterministic cleanup, and the reason destructors matter.
    • templatesCompile-time generics; the entire standard library is built from them.
    • virtual dispatchOverride polymorphically, with multiple inheritance when you need to mix behaviours.
    • move semanticsOwnership moves instead of copying — no redundant allocations, no surprise copies.
    • constexprComputation folded into the compile, so the runtime pays nothing.
    the problem it solves
    Systems programmers wanted Simula’s abstraction without paying runtime for it. C++ promised zero-cost OOP on C’s metal.
    the problem it carries
    The manual: a dozen ways to initialize, C’s undefined behavior inherited intact — plus compile times all its own.

    run it today

    runc++ fact.cpp -o fact && ./fact

    lineage ← C · ← Simula 67 · → Java

    C++ — 101 & 201

    struct File {
      FILE* f;
      explicit File(const char* p) : f(fopen(p, "r")) {}
      ~File() { if (f) fclose(f); }  // guaranteed
    };

    C++, 1985

  • the innovation — the mailbox

    The mailbox: every process owns one, messages are the only shared thing, crashes are isolated and supervised — nine nines, designed into the grammar.

    • pattern-matching clausesEach clause is one case; unmatched input is an error rather than a surprise.
    • processes and messagesMillions of isolated processes that communicate only by sending each other terms.
    • immutabilityNo shared mutable state, so data races are designed out rather than debugged.
    • supervisionCrashes are expected: a supervisor restarts a clean copy, and the fault never spreads.
    the problem it solves
    Telephone switches must never go down. Erlang made concurrency, distribution and fault-tolerance primitives of the language.
    the problem it carries
    Numerically slow, syntactically alien, and a hiring pool the size of its home town — brilliant for the nine-nines niche.

    run it today

    installbrew install erlang

    runescript fact.erl

    Erlang — 101 & 201

    loop() ->
      receive
        {ping, From} -> From ! pong, loop();
        stop         -> ok
      end.

    Erlang, 1986

  • the innovation — the one-liner

    The one-liner: regular expressions in the syntax, text as the native material — the duct tape that held the early web together.

    • context sensitivityOne value, many meanings — scalar, list or hash — decided by what surrounds it.
    • regular expressions, nativePattern matching is part of the language, with substitutions and transliterations built in.
    • hashes and listsThe two workhorses: an ordered map and a flat sequence cover most real jobs.
    • the one-linerChained operators finish a whole job in a line — the reason Perl outlived its critics.
    the problem it solves
    Reports, logs and glue: text processing where C was too heavy and shell too weak. Perl made the one-liner a deliverable.
    the problem it carries
    Write-only code — sigils, context, and “more than one way” means every script is its own dialect; the Perl 6 saga broke momentum.

    run it today

    runperl fact.pl

    Perl — 101 & 201

    while (<>) {
      s/^\s+//;             # trim
      print if /error/i;   # filter
    }

    Perl, 1987

The Web Opens

Suddenly code runs wherever a browser is. Java promises write-once-run-anywhere; JavaScript is written in ten days and becomes the most deployed language in history. Scripting wins the long game.

  • the innovation — the infinite list

    The infinite list: laziness means the primes can be defined as a sieve over all numbers — purity keeps it honest, monads keep effects at the border.

    • pure functionsNo side effects in the core: a result depends only on its arguments.
    • lazy evaluationValues are computed when needed, so infinite structures are perfectly ordinary.
    • effects in the type systemIO is a type, so the compiler separates the pure core from the impure edge.
    • pattern matching and guardsDecomposition and conditions are built into the language, not bolted on.
    the problem it solves
    Functional research needed a standard. Haskell committed: purity, laziness, and effects disciplined by the type system.
    the problem it carries
    Monad tutorials for decades, performance that must be profiled lazily, and adoption that curves like its own evaluation.

    run it today

    installbrew install ghc

    runrunghc fact.hs

    lineage ← ML

    Haskell — 101 & 201

    primes = sieve [2 ..]
      where
        sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0]

    Haskell, 1990

  • the innovation — visible structure

    Structure you can see: the indentation is the program — no braces between you and the algorithm, and a standard library with batteries included.

    • indentation as structureBlocks are indentation — no braces to misplace, and the file reads as it executes.
    • batteries includedThe standard library covers files, JSON, dates, networking and testing out of the box.
    • duck typingObjects work by the operations they support, not by a declared type.
    • comprehensionsMap and filter written as expressions, and fast enough to leave in production code.
    the problem it solves
    Teaching and scripting needed one language readable enough to feel like pseudocode but real enough to ship.
    the problem it carries
    The GIL — one thread of Python at a time — plus an interpreter pace it spent thirty years apologizing for.

    run it today

    runpython3 fact.py

    Python — 101 & 201

    for port in ["osaka", "genoa"]:
        print("next stop: %s" % port)

    Python, 1991

  • the innovation — the do block

    The block: iteration written as literature — each, select, map with the loop’s body handed over in place. Designed for programmer joy, and it shows.

    • blocks everywhereEvery method can take a block — iteration is a first-class idea, not a keyword.
    • everything is an objectEven nil and integers answer to the same protocol, so the language has one rule.
    • open classesReopen any class to add behaviour — a freedom that has also caused decades of grief.
    • metaprogrammingdefine_method and method_missing let code write code at run time.
    the problem it solves
    Programmer joy: Matz optimized for human happiness — productivity first, elegance as a feature, not an accident.
    the problem it carries
    Slower than its peers, hospitable to monkey-patch chaos, and its fate married to a single framework.

    run it today

    runruby fact.rb

    lineage ← Smalltalk-80

    Ruby — 101 & 201

    %w[perch sundial graymail]
      .each { |app| puts app.capitalize }

    Ruby, 1995

  • the innovation — the virtual machine

    The virtual machine: one binary, any machine — garbage collection and sandboxing as platform promises. Write once, run anywhere; eventually, run everywhere.

    • the JVMA virtual machine with garbage collection, JIT compilation and a security sandbox.
    • managed memoryMemory safety without manual management — and without a garbage-collection pause-free miracle.
    • interfaces and genericsContracts as first-class types, and compile-time genericity with erasure behind it.
    • checked exceptionsErrors declared in the signature, so callers cannot forget them.
    the problem it solves
    C++ was unsafe in practice and unportable in deployment. The JVM made garbage collection and portability platform promises.
    the problem it carries
    Ceremony — the factory-abstract-singleton years — verbose types, and a runtime footprint that starts in megabytes.

    run it today

    installbrew install openjdk

    runjava fact.java

    lineage ← C++ · → C#

    Java — 101 & 201

    public class Hello {
      public static void main(String[] args) {
        System.out.println("ahoy");
      }
    }

    Java, 1995

  • the innovation — the closure

    The closure: functions that remember where they were born — Scheme semantics in C’s clothing, shipped in ten days, now running nearly every screen on Earth.

    • first-class functionsFunctions are values: passed, returned, stored in objects and arrays.
    • closuresA function remembers where it was born — the module pattern and half of JS idiom follow.
    • prototypesObjects delegate to a shared prototype: inheritance without classes.
    • the event loopOne thread and a queue; promises schedule continuations on top of it.
    the problem it solves
    The browser needed scripting, immediately. Eich shipped Scheme dynamics in C’s clothing — in ten days.
    the problem it carries
    Designed in ten days: coercion surprises, this-binding puzzles — and permanent: the language the web can never remove.

    run it today

    installbrew install node

    runnode fact.js

    lineage ← Scheme · → TypeScript

    JavaScript — 101 & 201

    function counter() {
      let n = 0;
      return () => ++n;
    }
    counter()();  // 1

    JavaScript, 1995

  • the innovation — the page template

    The page template: code inside the document, the document inside the code — the long tail of the web, written between two tags.

    • templating in the pageHTML and code interleaved — the page is the program, and deploying is uploading a file.
    • superglobals and extensionsRequest, session and filesystem are one function call away.
    • coercive typingTypes are checked and converted loosely, on purpose — the price of templating.
    • one array typeAn ordered map does duty as list, dictionary and tuple alike.
    the problem it solves
    Dynamic pages required CGI gymnastics. PHP made the server-side behavior of a page as easy to write as the page itself.
    the problem it carries
    An stdlib that grew by accretion — inconsistent names, forgiving-by-default behavior, and a security reputation earned early.

    run it today

    installbrew install php

    runphp fact.php

    PHP — 101 & 201

    <ul>
    <?php foreach ($crew as $name): ?>
      <li><?= htmlspecialchars($name) ?></li>
    <?php endforeach; ?>
    </ul>

    PHP, 1995

Multicore & Missions

Moore’s law flattens; phones and clouds arrive. The new bets are concurrency and safety — Go makes channels primitive, Rust makes memory bugs compile errors, TypeScript types the world’s most popular language.

  • the innovation — the case class

    The case class: data with dignity — immutable, pattern-matchable, one line to declare. Objects and functions finally married, on the JVM.

    • case classesImmutable data with pattern matching, equality and copy, in one line.
    • traits and mixinsCompose behaviour from pieces, linearized like Smalltalk’s.
    • for-comprehensionsMonadic sequencing that reads like a loop; Spark queries are written this way.
    • immutability by defaultvals are values, so sharing is safe by construction.
    the problem it solves
    The JVM without Java’s ceremony: full functional programming and object orientation on a battle-tested platform.
    the problem it carries
    Two sublanguages under one name — compile-time wizards and everyone else — plus compile times that tested loyalty.

    run it today

    installbrew install scala

    runscala fact.scala

    Scala — 101 & 201

    case class Ship(name: String, tons: Int)
    
    val total = ships.map(_.tons).sum

    Scala, 2004

  • the innovation — the channel

    The channel: goroutines meet on typed pipes — Hoare’s CSP made ordinary, concurrency made a primitive.

    • goroutines and channelsCSP concurrency as syntax: go, make(chan), and a receive operator.
    • multiple return valuesErrors are ordinary return values, not exceptions or sentinels.
    • implicit interfacesAny type with the right methods satisfies the interface — no declaration required.
    • fast buildsOne toolchain and sub-second compiles, which is a feature the whole ecosystem feels.
    the problem it solves
    Google’s builds were slow and its concurrency error-prone. Go bet everything on simplicity, speed, and CSP channels.
    the problem it carries
    Simplicity enforced: no generics for thirteen years, if err != nil as a lifestyle, and runtime magic under a plain exterior.

    run it today

    installbrew install go

    rungo run fact.go

    Go — 101 & 201

    ch := make(chan string)
    go func() { ch <- "done" }()
    fmt.Println(<-ch)

    Go, 2009

  • the innovation — the gradual type

    The gradual type: types that check, not obstruct — JavaScript with a contract, adopted by the mainstream without rewriting the world.

    • gradual typingAnnotate as much or as little as you like; the annotations vanish at run time.
    • structural interfacesCompatibility is by shape, not by declaration — interfaces are structural.
    • union narrowingThe compiler tracks which cases are possible at each point and rejects the rest.
    • declaration mergingTypes can be extended from other files — the basis of plugins and augmentation.
    the problem it solves
    JavaScript at scale had no safety net. TypeScript added types that check — then erase — without leaving the ecosystem.
    the problem it carries
    The types vanish at runtime; any is a trapdoor; and you maintain two languages in your head forever.

    run it today

    runbunx tsx fact.ts

    lineage ← JavaScript

    TypeScript — 101 & 201

    function tally(xs: number[]): number {
      return xs.reduce((a, b) => a + b, 0);
    }
    tally("123");  // error: not assignable

    TypeScript, 2012

  • the innovation — the optional

    The optional: null moves into the type system — you cannot forget the nil case, because the compiler will not let you.

    • optionalsNil lives in the type system, and unwrapping is explicit and checked.
    • value semanticsStructs copy, classes reference — the choice is visible in the declaration.
    • protocols with associated typesAbstractions without inheritance, expressible without naming a supertype.
    • whole-module optimizationThe compiler sees the entire module, so generics specialize and cross-file calls inline.
    the problem it solves
    Objective-C repelled newcomers and memory bugs persisted. Swift made safety the default and modern syntax the attraction.
    the problem it carries
    A decade of source-breaking churn, an ABI saga — and gravity: it lives almost entirely inside Apple’s orbit.

    run it today

    runswift fact.swift

    Swift — 101 & 201

    var port: String? = "osaka"
    
    if let p = port {
      print(p.uppercased())
    }

    Swift, 2014

  • the innovation — the borrow

    The borrow: every value has one owner, every reference a lease — memory safety without a garbage collector, enforced before the program exists.

    • ownership and borrowingOne owner, checked borrows, and lifetimes — use-after-free cannot be written.
    • algebraic enumsVariants carry their own data, and match must handle every case.
    • traits and genericsShared behaviour with zero-cost dispatch after monomorphization.
    • Result and error handlingFailure is a value in the signature, so it cannot be ignored by accident.
    • cargoOne tool builds, tests, documents and publishes — and resolves dependencies correctly.
    the problem it solves
    Systems code without memory bugs: ownership instead of garbage collection, safety without a runtime tax.
    the problem it carries
    The borrow checker’s learning curve — months of fighting the compiler — and compile times that reward patience.

    run it today

    installbrew install rust

    runrustc fact.rs -o fact && ./fact

    lineage ← OCaml

    Rust — 101 & 201

    let ships = vec!["perch", "sundial"];
    let first = &ships[0];
    // ships.push("graymail");  // error: borrow in use
    println!("{first}");

    Rust, 2015

The Fluent Age

We arrive where we started: explaining intent in our own words. Every language ever built becomes the model’s vocabulary; the prompt becomes the highest-level language yet. The machine, at last, writes the assembly.

  • the innovation — the completion

    The completion: a comment is the spec, the model writes the body — prediction becomes a programming interface.

    • prediction as the interfaceThe next lines are guessed from context; you accept, reject or steer.
    • the comment as specA comment in the right context is often enough to define the function to be written.
    • whole-file awarenessSuggestions consider the file, not just the line under the cursor.
    the problem it solves
    Most programming is boilerplate already written somewhere. The model predicts the code from intent — a comment as spec.
    the problem it carries
    Confident wrongness: plausible code, wrong licenses, and a debate about what skill remains when the first draft is free.

    run it today

    No toolchain — an editor. Install the Copilot extension in VS Code, type the comment, and accept the ghost text with Tab.

    Copilot — 101 & 201

    # reverse a linked list, iteratively
    def reverse(head):
        prev = None
        while head:
            head.next, prev, head = prev, head.next, head
        return prev

    Copilot, 2021

  • the innovation — the fast path

    The fast path: fn and struct mark the zero-cost roads through a Python-shaped language — syntax borrowed wholesale, performance reclaimed.

    • fn and defTwo worlds in one language: a fast compiled fn, and a relaxed Python-like def.
    • structCompile-time data layout with no hidden overhead, ML-style.
    • static typingTypes where you want them, inferred where you do not.
    • GPU-nativeBuilt for accelerators from the start, not bolted on afterwards.
    the problem it solves
    Python owns AI research but not its hardware. Mojo keeps the syntax and reclaims the performance — one language for lab and kernel.
    the problem it carries
    Young, single-vendor, and starting its ecosystem from zero; the bet is huge and unproven at scale.

    run it today

    installcurl -ssL https://get.modular.com | bash -

    runmojo run fact.mojo

    Mojo — 101 & 201

    fn fact(n: Int) -> Int:
        var r = 1
        for i in range(1, n + 1):
            r *= i
        return r

    Mojo, 2023

  • the innovation — the intent

    The intent: say what the page should do, receive working code — natural language as the top of the language stack, every prior language beneath it.

    • intent as inputYou describe the outcome; the model writes the code that produces it.
    • iteration as the loopRefine by talking — each turn rewrites the artifact rather than patching it.
    • context as the programFiles, examples and constraints supplied in the prompt shape the output more than the words do.
    • verification debtCorrectness now depends on checking the result, not on the type system.
    the problem it solves
    Syntax was programming’s last gatekeeper. Prompts let anyone describe the result — and receive working code.
    the problem it carries
    No spec, no types, no determinism: the same prompt, a different program. Verification becomes the job.

    run it today

    The tooling is a text box. Paste the specimen into any chat assistant — or straight into an agent that writes the file.

    Prompts — 101 & 201

    Make a timeline page of shipping
    routes, navy aesthetic, vanilla JS.

    Prompts, 2023→

  • the innovation — the blank page

    The blank page: every era in this guide began exactly here — version 0.1, somewhere, right now.

    • unknown, by definitionBut the shape of the last three decades points one way: less syntax, more intent, more machine.
    • the constantEvery era’s new language announces that it ends the story. None has yet.
    • the live constraintsEnergy, verification and AI-native semantics are the pressures the next language will answer.
    the problem it solves
    Whatever the next wall is — energy, correctness, AI-native semantics — someone is writing version 0.1 for it right now.
    the problem it carries
    Every era in this guide believed its language was the last one. None has been.

    run it today

    No install. Open a new file and write version 0.1.

    What’s next — 101 & 201

    // version 0.1 — someone, somewhere,
    // is typing the first line right now

    What’s next, ∞

§ 03 — Schools

Six schools of thought

Languages are arguments about how to think. The schools below were rivals for forty years; modern languages descend from all of them.

01

goto

Imperative

Tell the machine every step, in order. The oldest school — assembly’s direct heir — where a program is a recipe and state changes command by command.

FORTRAN · COBOL · C

02

begin…end

Structured

Dijkstra’s 1968 letter made the goto heresy. Programs become nested blocks, loops and procedures — shapes a person can reason about, and a prover can check.

ALGOL · Pascal · C

03

class

Object-oriented

Simula’s classes and Smalltalk’s messages wrap state with behavior. Data learns to protect itself; the decade of the framework follows.

Simula · Smalltalk · C++ · Java

04

λ

Functional

LISP’s heresy: programs as values. First-class functions, immutability, inferred types — dismissed as academic for forty years, now in every mainstream language.

LISP · ML · Haskell

05

:-

Logic & declarative

State the facts, ask the question. From Prolog’s rules to SQL’s SELECT — describe the result you want, let the machine find the path.

Prolog · SQL · Datalog

06

match

The Convergence

The war ended in intermarriage. Today’s languages borrow from every school — closures, actors, pattern matching, traits. Multi-paradigm wins.

Rust · Swift · Python · Kotlin

§ 04 — The matrix

Every language, feature by feature

36 languages against 14 capabilities, in six families. The deeper the square, the more that feature defines the language.

canonical present partial absenthover a column to isolate it · click a family to isolate that band
A matrix comparing 36 programming languages across 14 language features, in six families: type system, memory, model, runtime, structure, ergonomics. Each cell says how far a language carries a capability: absent, partial, present or canonical.
language36 entries
typesinfergcsafetyobjectsfunctionslazyclosuresconcerrorsmodulesmetaexprscript
1940sThe Wired Age
Plankalkül1945absent — typesabsent — inferenceabsent — garbage collectionpartial — memory safetyabsent — objectspartial — functions as valuespartial — lazinessabsent — closuresabsent — concurrencyabsent — exceptionspartial — modulesabsent — metaprogrammingabsent — expressionsabsent — scripting
Short Code1949absent — typesabsent — inferenceabsent — garbage collectionabsent — memory safetyabsent — objectsabsent — functions as valuesabsent — lazinessabsent — closuresabsent — concurrencyabsent — exceptionsabsent — modulesabsent — metaprogrammingcanonical — expressionspartial — scripting
Autocode1952partial — typesabsent — inferenceabsent — garbage collectionabsent — memory safetyabsent — objectsabsent — functions as valuesabsent — lazinessabsent — closuresabsent — concurrencyabsent — exceptionsabsent — modulesabsent — metaprogrammingpresent — expressionspartial — scripting
A-01952partial — typesabsent — inferenceabsent — garbage collectionabsent — memory safetyabsent — objectspartial — functions as valuesabsent — lazinessabsent — closuresabsent — concurrencyabsent — exceptionspresent — modulesabsent — metaprogrammingabsent — expressionspartial — scripting
1950sThe Compiler Age
FORTRAN1957canonical — typesabsent — inferenceabsent — garbage collectionpartial — memory safetypartial — objectspartial — functions as valuesabsent — lazinessabsent — closurespartial — concurrencypartial — exceptionscanonical — modulespresent — metaprogrammingpresent — expressionspartial — scripting
LISP1958absent — typesabsent — inferencecanonical — garbage collectionpresent — memory safetypresent — objectscanonical — functions as valuespartial — lazinesscanonical — closurespartial — concurrencypresent — exceptionspresent — modulescanonical — metaprogrammingpresent — expressionscanonical — scripting
COBOL1959canonical — typesabsent — inferenceabsent — garbage collectionpartial — memory safetypartial — objectsabsent — functions as valuesabsent — lazinessabsent — closuresabsent — concurrencypartial — exceptionspartial — modulespresent — metaprogrammingabsent — expressionspartial — scripting
ALGOL 601960present — typesabsent — inferenceabsent — garbage collectionpartial — memory safetyabsent — objectspresent — functions as valuespresent — lazinesspartial — closurespartial — concurrencyabsent — exceptionspartial — modulesabsent — metaprogrammingpresent — expressionspartial — scripting
1970sThe Systems Age
Simula 671967canonical — typesabsent — inferencepresent — garbage collectionpartial — memory safetycanonical — objectspartial — functions as valuesabsent — lazinessabsent — closurespresent — concurrencyabsent — exceptionspartial — modulesabsent — metaprogrammingpartial — expressionsabsent — scripting
Pascal1970canonical — typesabsent — inferenceabsent — garbage collectionpartial — memory safetypartial — objectspartial — functions as valuesabsent — lazinessabsent — closuresabsent — concurrencyabsent — exceptionspresent — modulesabsent — metaprogrammingpartial — expressionspartial — scripting
C1972canonical — typesabsent — inferenceabsent — garbage collectionabsent — memory safetypartial — objectspartial — functions as valuesabsent — lazinessabsent — closurespartial — concurrencyabsent — exceptionspartial — modulespresent — metaprogrammingpresent — expressionspresent — scripting
Prolog1972partial — typesabsent — inferencepresent — garbage collectionpresent — memory safetyabsent — objectspresent — functions as valuesabsent — lazinesspartial — closurespresent — concurrencypresent — exceptionspartial — modulespresent — metaprogrammingpartial — expressionspresent — scripting
ML1973canonical — typescanonical — inferencepresent — garbage collectioncanonical — memory safetypartial — objectscanonical — functions as valuesabsent — lazinesscanonical — closurespartial — concurrencypresent — exceptionscanonical — modulespresent — metaprogrammingpresent — expressionspresent — scripting
Scheme1975absent — typesabsent — inferencecanonical — garbage collectionpresent — memory safetypartial — objectscanonical — functions as valuespartial — lazinesscanonical — closurespartial — concurrencypartial — exceptionspresent — modulescanonical — metaprogrammingpresent — expressionscanonical — scripting
SQL1974present — typesabsent — inferenceabsent — garbage collectionabsent — memory safetyabsent — objectspartial — functions as valuesabsent — lazinessabsent — closurespartial — concurrencypartial — exceptionsabsent — modulesabsent — metaprogrammingpartial — expressionspresent — scripting
1980sObjects Ascendant
Smalltalk-801980present — typesabsent — inferencecanonical — garbage collectionpresent — memory safetycanonical — objectspresent — functions as valuesabsent — lazinesscanonical — closurespartial — concurrencypresent — exceptionspresent — modulescanonical — metaprogrammingpartial — expressionscanonical — scripting
Ada1983canonical — typesabsent — inferencepresent — garbage collectioncanonical — memory safetypresent — objectspartial — functions as valuesabsent — lazinessabsent — closurescanonical — concurrencycanonical — exceptionscanonical — modulespresent — metaprogrammingpartial — expressionsabsent — scripting
Objective-C1984present — typesabsent — inferencepresent — garbage collectionpartial — memory safetycanonical — objectspresent — functions as valuesabsent — lazinesspresent — closurespresent — concurrencypresent — exceptionspartial — modulescanonical — metaprogrammingpartial — expressionspresent — scripting
C++1985canonical — typesabsent — inferencepresent — garbage collectionpresent — memory safetycanonical — objectspresent — functions as valuesabsent — lazinesscanonical — closurespresent — concurrencypresent — exceptionspresent — modulescanonical — metaprogrammingpresent — expressionspartial — scripting
Erlang1986present — typesabsent — inferencecanonical — garbage collectioncanonical — memory safetyabsent — objectscanonical — functions as valuesabsent — lazinesscanonical — closurescanonical — concurrencypresent — exceptionspresent — modulespresent — metaprogrammingpresent — expressionspresent — scripting
Perl1987partial — typesabsent — inferencecanonical — garbage collectionpresent — memory safetypresent — objectspresent — functions as valuesabsent — lazinesscanonical — closurespartial — concurrencypresent — exceptionspresent — modulescanonical — metaprogrammingcanonical — expressionscanonical — scripting
1990sThe Web Opens
Haskell1990canonical — typescanonical — inferencepresent — garbage collectioncanonical — memory safetypartial — objectscanonical — functions as valuescanonical — lazinesscanonical — closurespresent — concurrencypresent — exceptionscanonical — modulescanonical — metaprogrammingpresent — expressionspartial — scripting
Python1991present — typesabsent — inferencecanonical — garbage collectionpresent — memory safetypresent — objectspresent — functions as valuespartial — lazinesscanonical — closurespresent — concurrencycanonical — exceptionscanonical — modulescanonical — metaprogrammingpresent — expressionscanonical — scripting
Ruby1995partial — typesabsent — inferencecanonical — garbage collectionpresent — memory safetycanonical — objectspresent — functions as valuesabsent — lazinesscanonical — closurespresent — concurrencypresent — exceptionscanonical — modulescanonical — metaprogrammingcanonical — expressionscanonical — scripting
Java1995canonical — typesabsent — inferencecanonical — garbage collectioncanonical — memory safetycanonical — objectspresent — functions as valuesabsent — lazinesscanonical — closurescanonical — concurrencycanonical — exceptionscanonical — modulespresent — metaprogrammingpartial — expressionspresent — scripting
JavaScript1995partial — typesabsent — inferencecanonical — garbage collectionpresent — memory safetypresent — objectscanonical — functions as valuesabsent — lazinesscanonical — closurespresent — concurrencypresent — exceptionscanonical — modulescanonical — metaprogrammingcanonical — expressionscanonical — scripting
PHP1995present — typesabsent — inferencecanonical — garbage collectionpresent — memory safetypresent — objectspresent — functions as valuespresent — lazinesscanonical — closurespresent — concurrencycanonical — exceptionscanonical — modulespresent — metaprogrammingpresent — expressionscanonical — scripting
2000sMulticore & Missions
Scala2004canonical — typespresent — inferencecanonical — garbage collectioncanonical — memory safetycanonical — objectscanonical — functions as valuespresent — lazinesscanonical — closurescanonical — concurrencypresent — exceptionscanonical — modulescanonical — metaprogrammingcanonical — expressionspresent — scripting
Go2009canonical — typesabsent — inferencepresent — garbage collectionpresent — memory safetypartial — objectspartial — functions as valuesabsent — lazinesspresent — closurescanonical — concurrencypartial — exceptionscanonical — modulespartial — metaprogrammingpartial — expressionscanonical — scripting
TypeScript2012canonical — typescanonical — inferencecanonical — garbage collectioncanonical — memory safetypresent — objectspresent — functions as valuesabsent — lazinesscanonical — closurespresent — concurrencypresent — exceptionscanonical — modulespresent — metaprogrammingcanonical — expressionscanonical — scripting
Swift2014canonical — typespresent — inferencecanonical — garbage collectioncanonical — memory safetycanonical — objectspresent — functions as valuesabsent — lazinesscanonical — closurescanonical — concurrencycanonical — exceptionscanonical — modulespresent — metaprogrammingpresent — expressionspresent — scripting
Rust2015canonical — typescanonical — inferenceabsent — garbage collectioncanonical — memory safetypresent — objectspresent — functions as valuesabsent — lazinesscanonical — closurescanonical — concurrencycanonical — exceptionscanonical — modulescanonical — metaprogrammingpartial — expressionspresent — scripting
2020sThe Fluent Age
Copilot2021partial — typesabsent — inferencecanonical — garbage collectionpartial — memory safetypartial — objectspartial — functions as valuespartial — lazinesspartial — closurespartial — concurrencypartial — exceptionspartial — modulescanonical — metaprogrammingpartial — expressionscanonical — scripting
Mojo2023canonical — typespresent — inferenceabsent — garbage collectioncanonical — memory safetypresent — objectscanonical — functions as valuesabsent — lazinesspresent — closurescanonical — concurrencypartial — exceptionspresent — modulespartial — metaprogrammingcanonical — expressionspresent — scripting
Prompts2023→absent — typesabsent — inferencepartial — garbage collectionabsent — memory safetyabsent — objectspartial — functions as valuesabsent — lazinessabsent — closuresabsent — concurrencyabsent — exceptionsabsent — modulescanonical — metaprogrammingpartial — expressionscanonical — scripting
What’s next∞absent — typesabsent — inferenceabsent — garbage collectionabsent — memory safetyabsent — objectsabsent — functions as valuesabsent — lazinessabsent — closuresabsent — concurrencyabsent — exceptionsabsent — modulesabsent — metaprogrammingabsent — expressionsabsent — scripting
canonical count164141088117861414712

Read it down a column to see who carries a capability; read it across a row to see what defines one language. The strip at the foot counts the languages that hold each capability canonically.

§ 05 — Specimens

One program, seven ways

The same little function — n factorial — pinned and mounted from every era. Watch the ceremony fall away, then return as types.

specimen · fortran1957
      FUNCTION NFACT(N)
      NFACT = 1
      DO 10 I = 1, N
   10   NFACT = NFACT * I
      END

§ 06 — Questions

What people actually ask

The questions this guide keeps answering — collected in one place, with the short version of the long version.

What was the first programming language?

Plankalkül, designed by Konrad Zuse in 1945 — assignment, subprograms and structured data, written for a machine that did not exist. It stayed in a drawer for decades and was first executed only in 2000, reconstructed from Zuse’s own paper. The first language anyone actually ran was Short Code (1949), and the first to compile itself into machine code was Autocode (1952).

Plankalkül — the 101

Which language was the first to be compiled?

FORTRAN (1957) was the first production compiler — John Backus’s team proved that a machine could translate high-level mathematics into code as fast as a programmer could hand-write it. The idea existed earlier: Alick Glennie’s Autocode compiled formulas in 1952, and Grace Hopper’s A-0 called library routines in 1952.

FORTRAN — the 101

Which language invented garbage collection?

LISP, in 1958. John McCarthy needed memory the machine could not spare, so the runtime reclaimed it — and every managed language since, from Smalltalk to Java to Swift, inherited the idea.

LISP — the 101

Which language introduced type inference?

ML, in 1973. Robin Milner’s system deduced a function’s type from its definition instead of reading it from an annotation, using what is now called Hindley–Milner inference. Haskell, OCaml, F# and Rust all descend from that decision.

ML — the 101

Who invented the object?

Ole-Johan Dahl and Kristen Nygaard, in Simula 67 (1967), who added the class, the subclass and inheritance to simulate ships in a Norwegian fjord. Alan Kay’s Smalltalk (1980) then made everything an object and every interaction a message.

Simula 67 — the 101

Is the goto statement really that bad?

Dijkstra’s 1968 letter argued that uncontrolled goto made programs unprovable, and structured programming answered with blocks, loops and single-exit procedures. But a goto is not inherently evil — C, Go and Rust all keep one for cases where no cleaner structure exists. The argument was never about the keyword; it was about who controls the flow.

ALGOL 60 — the 101

Who were the first programmers?

Before software existed, programming was wiring. From 1943 the ENIAC women programmed the machine by setting switches and patch cables — they wrote the first algorithms for the first stored-program computer, and their notes on the machine were the first published programs of any kind. The word “software” would not appear in print until 1958.

Plankalkül — the 101

Which programming language should I learn first?

Python, if your goal is to understand programming quickly: it has the least ceremony and the largest ecosystem. Go if you want a job in infrastructure and a language that teaches concurrency in an afternoon. Rust if you want to learn what memory really costs. SQL if your work involves data — half the job is knowing how to ask for things.

Python — the 101

What is the most used programming language?

It depends what you count. JavaScript runs on essentially every device with a screen, so it wins on deployed instances. Python leads adoption, teaching and most AI workloads. Java and C# still hold the enterprise back office. C and C++ remain underneath the operating systems, browsers, databases and game engines — the substrate nobody counts.

JavaScript — the 101