Vivian Voss

Why Mathematicians Design Languages

architecture performance

On Second Thought ■ Episode 1

Every mainstream programming language was designed by a mathematician. Turing: state machines. Church: lambda calculus. Backus: FORTRAN (FORmula TRANslation, the name rather gives it away). McCarthy: Lisp. Hoare: formal verification. Dijkstra: programs as mathematical proofs.

Not one linguist in the room. One does wonder what might have happened if someone had invited one.

The Inheritance

Their metaphor was the equation. Variables are bindings. Types are sets. Functions are mappings from domain to codomain. Errors interrupt control flow because in mathematics, an invalid step terminates the proof. The entire edifice of modern programming rests on a single premise: that telling a machine what to do is fundamentally an act of mathematics.

In 1936, this made perfect sense. Turing was not building software. He was settling a question in mathematical logic. Church was not designing an API. He was formalising the notion of computability itself. The mathematical foundations were not an arbitrary choice. They were the only foundations available.

Ninety years later, we are still writing in their notation. Somewhat less reasonable, that.

The Founders: All Mathematicians Church (1932) Lambda calculus Functions as first-class values Turing (1936) State machines Tape, head, rules Backus (1957) FORTRAN, BNF FORmula TRANslation McCarthy (1958) Lisp Lambda calculus as syntax Hoare (1965) Formal verification null: "my billion-dollar mistake" Dijkstra (1976) Programs as proofs Structured programming Linguists invited: 0 Their metaphor: the equation. Variables are bindings. Types are sets. Errors halt execution because in mathematics, an invalid step terminates the proof. Ninety years later, we are still writing in their notation.

The Cost

Natural language inflects. Run, runs, running. The word changes form to carry meaning. The same root, shaped by context, communicates tense, person, and aspect without a single keyword. A three-year-old masters this before learning to tie shoelaces.

In code, a function is a function is a function. The word never learns to conjugate. We compensate with keywords: async, static, public, virtual, override. Five adjectives bolted onto a noun because the noun cannot inflect. A language that understood morphology would not need them. The form itself would carry the meaning, the way ran carries past tense without an annotation.

Natural language scopes through context. “Here” means something different in every room. You do not declare which room you are in. You know. Everyone in the conversation knows. The context is shared, implicit, and unambiguous precisely because it is situated.

Code offers three boxes: local, module, global. Chosen in 1967 by Simula, refined by nobody. A toddler navigates contextual scope before learning to count. Our languages still cannot.

Natural language composes. “Bookshelf” is not a class that inherits from Book and implements Shelf. It is two nouns pressed together, and every English speaker alive knows instantly what it means. The compound word is the path: book, then shelf. The structure is the meaning.

One rather wishes one could say the same about AbstractSingletonProxyFactoryBean.

What Natural Language Already Knows Natural: Inflection run, runs, running Form carries meaning. No keywords vs Code: Keywords async static public virtual override Five adjectives bolted onto a noun Natural: Context "Here" means something different in every room A toddler masters this before counting vs Code: Declaration local, module, global Three boxes, chosen in 1967 Natural: Composition "Bookshelf" = book + shelf Two nouns. Instantly understood vs Code: Inheritance AbstractSingletonProxyFactoryBean Five nouns. Nobody is quite sure

The Proof

Haskell is the purest mathematical language ever built. Lambda calculus, category theory, monads. Exquisite. Market share: 0.1 per cent. If mathematical elegance were the right metric, Haskell would have won decades ago. It rather conspicuously did not.

COBOL, designed by Grace Hopper to read like English, still processes 95 per cent of ATM transactions. Larry Wall studied linguistics before creating Perl. Yukihiro Matsumoto designed Ruby around how humans read, not how compilers parse. The languages that endure are not the ones with the purest type theory. They are the ones whose authors, consciously or not, borrowed from linguistics.

Language itself is programming: ten thousand years of debugging by seven billion concurrent users. One rather suspects the test coverage exceeds that of any formal verification suite.

Mathematical Elegance vs Linguistic Readability Haskell 0.1% Lambda calculus, monads, category theory COBOL 95% of ATM transactions. Reads like English Designed by Grace Hopper. A linguist by instinct, if not by title. If mathematical elegance were the right metric, Haskell would have won.

The Linguistic Concepts We Never Used

Consider what a programming language might look like if it borrowed from linguistics rather than mathematics. Not as a thought experiment. As a genuine question about the foundations we chose and the foundations we did not.

Inflection. Words change form to carry meaning. In English, capitalisation alone distinguishes a general noun from a proper noun. What if a programming language used the same convention? Uppercase is a thing. Lowercase is an action. Not by style guide. By grammar. Every reader instinctively knows the difference. No keyword required. The form is the type.

Agreement. In natural language, parts align without central authority. The verb agrees with the subject. The adjective agrees with the noun. Nobody declares this agreement. It emerges from the structure. What if properties in a program were not declared but emerged from agreement between components? Two things that share a property can interact. Two things that do not cannot. Not because a checker forbids it, but because without agreement, no interaction exists to have.

Contextual scope. “Here” resolves differently depending on where you stand. Not because a declaration tells you, but because context is inherent. What if scope in a program were a continuous zoom rather than three discrete boxes? You stand at one level and see the detail appropriate to that level. Zoom in: more detail, more specificity, but never a contradiction of what the outer level established. The way a city contains streets that contain buildings that contain rooms. Each level refines the previous one.

Composition. “Bookshelf” is two nouns pressed together. The compound word is a path: book, then shelf. What if navigation in a program worked the same way? Not request.user.name with three dots, but a single compound word that is the path? The structure is the meaning. The deeper you go, the longer the word. The programmer slides through resolution by writing, and the compiler follows.

Linguistic Concepts Programming Never Adopted Inflection Form carries meaning run, runs, running No keywords needed Agreement Parts align by nature No central authority Emergence, not declaration Context Scope as zoom level "Here" resolves by position Continuous, not three boxes Composition Compound = path Bookshelf = book + shelf Structure is meaning Ten thousand years of natural language. Seven billion concurrent users. One rather suspects the test coverage exceeds any formal verification suite. Mathematics describes fractals. Language IS fractal.

The Question

Mathematics belongs in the machine space. Compilers, memory layout, register allocation, instruction scheduling: proofs and formal logic do their finest work there, and one would not dream of replacing them. The machine is mathematics. That is where it should stay.

Consider an analogy from an entirely different domain. Human reproduction is an exquisitely biological process with rather consequential outcomes. One would always leave the mechanics in the biological space. But there is literature about it, and that literature can enhance, inspire, and indeed initiate the process. The language does not replace the biology. It prepares it. It communicates intent in ways the mechanism alone never could. It need not even be written down. “Your place or mine?” Four words. No formal specification. No proof of correctness. Yet depending on the subroutine currently running in the recipient, those four words either initiate the entire biological process or result in a rather firm slap. Same input. Different context. Different outcome. A linguist would call this pragmatics. A programmer would call it a runtime exception. Nobody has ever suggested that the solution to reproduction is more biology textbooks.

There is a deeper asymmetry here. Mathematics cannot exist without language. Every proof is written in sentences. Every axiom is a proposition. Every theorem is an argument, and arguments are made of words. Language, however, exists perfectly well without mathematics. A child speaks before it counts. A story moves you before you can formalise why. Language is immediate: the moment you receive it, you are already working with it. Mathematics is abstract: it must first be proven before it can be trusted. We built our programming languages on the discipline that requires proof and ignored the one that is proof.

The mathematician will object. Everything is expressible in mathematics, they will say. Every quark, every wave function, every structure in the universe reduces to equations. Language itself is merely a phenomenon that mathematics can describe. One admires the confidence. But it contains a rather fundamental error.

Mathematics is not the universe. It is a description of the universe, arrived at retrospectively, to account for something that already exists. Language, by contrast, does not describe what is. Language is. It precedes the description.

Bees signal distance and direction through dance. Trees warn their neighbours of parasites through fungal networks. Communication exists in species that have never produced a single mathematician, and yet everything in their environment works precisely as it best fits. Darwin called it survival of the fittest, and the word is worth lingering on: not the strongest, not the most optimal, but the best fitting. Fitting is not a mathematical concept. It is a contextual one. The organism that fits is the one that communicates with its environment, not the one that calculates it.

A mother speaks to her child before anyone writes an equation about phonetics. Humans told stories for forty thousand years before Euclid formalised geometry. The equation always arrives afterwards, formulated in language, to explain what language was already doing. Mathematics can describe language. But it does so in arrears, and it does so in sentences. The tool that claims primacy cannot even state its own claim without borrowing from the thing it claims to supersede.

And yet the language humans write code in is not machine space. It is communication. It is one human explaining intent to a compiler, and another human reading that intent six months later at half past two in the morning during an incident. The reader is not a proof assistant. The reader is tired, undercaffeinated, and hoping the variable name tells the truth.

Communication, it turns out, has structure. Language is fractal: a sentence contains clauses, clauses contain phrases, phrases contain words. The same pattern, composing at every level. Mathematics can describe fractals beautifully. But the formula is always more complex than the shape it describes. What if a programming language were the shape, not the formula? One form, composing at every level, from expression to module to system?

What if code inflected instead of overloading? Scope were context, not declaration? Types were agreements rather than sets? Composition were compound words rather than inheritance chains?

These are not rhetorical flourishes. They are design questions. And remarkably, two mathematicians asked them first. Backus, in his 1977 Turing Award lecture: “Can Programming Be Liberated from the von Neumann Style?” One does admire a mathematician who brings his own demolition crew. And in 2024, Andrew D. Gordon published “The Linguistics of Programming” at ACM Onward!, asking with peer-reviewed rigour whether programming language design might benefit from the discipline that studies how humans actually communicate. It took until 2024 for someone to publish the question formally. One suspects the linguists had been too polite to bring it up themselves.

So here we are. Ninety years of programming languages designed by mathematicians. Ninety years of keywords where inflection would do, declarations where context would suffice, inheritance hierarchies where a compound word would be clear. Ninety years of building the human interface with tools designed for the machine.

One is not suggesting answers. Merely noting that the question has been waiting rather patiently. And that the discipline best equipped to answer it has ten thousand years of production experience, seven billion concurrent users, and a test suite that no formal verification framework has ever come close to matching.

Mathematics cannot exist without language. Language exists perfectly well without mathematics. A child speaks before it counts. A proof is written in sentences. The tool that claims primacy cannot even state its claim without borrowing from the thing it claims to supersede. Ninety years of programming languages built on the discipline that requires proof. Not one built on the discipline that is proof.