Functional programming
The paradigm the corpus was carrying in pieces before this page existed. Nine of its languages are functional or part-functional — haskell, ocaml, fsharp, clojure, elixir, erlang, scheme, lisp, jq — and the founding synthesis treated “imperative/functional” as one undifferentiated axis. The 2026-08-12 research pass into functional TypeScript is what forced the split, because it exposed the question that actually separates these languages.
The axis: where the guarantee lives
Not whether a language is functional. What enforces it, and what happens to the enforcement at runtime. Four answers in this corpus, in descending order of how much the machine is doing:
- In the type system, checked and load-bearing. haskell: purity, immutability by default,
laziness and static types presented as one commitment. Effects are values of type
IO aand the compiler will not let them pass for ana. ocaml sits nearby with a weaker version — an industrial-strength functional core that keeps mutation available and a GC alongside it. - In the data model. clojure: immutable persistent data structures are what the language is made of, and STM rides on top of that. The guarantee is about the values at runtime, not the annotations at compile time — which is why concurrency falls out of it (see concurrency-model).
- In the runtime’s isolation. elixir and erlang: state exists, but nothing is shared, so the effects of mutation cannot cross a process boundary. Purity is not claimed; the hazard purity usually removes is removed anyway.
- In a library, over a host that guarantees nothing. typescript with effect or fp-ts. This is the case that makes the axis visible, because here the enforcement is a type layer that deletes itself at compile time and a host language, JavaScript, that has declined to add immutable values (records-and-tuples).
The fourth answer is the interesting one, and it is not a lesser version of the first three. It is a different thing: a discipline the tooling can check while you write and nothing can check while you run.
What a library can and cannot retrofit
The TypeScript case is a controlled experiment in what a paradigm needs from its language, because the community tried to import Haskell wholesale and the failures are documented.
Retrofitted successfully — composition, Option/Either in place of null and exceptions, typed
error channels, dependency injection through a type parameter. All of it lives in the type layer,
which is exactly where TypeScript is strong (type-system).
Retrofitted at a cost — abstraction over type constructors, which the language cannot express.
fp-ts imports an OCaml technique from lightweight-hkt (brands plus an app type, i.e. type
defunctionalization) whose own authors state that the checker then cannot catch ill-kinded encodings.
ocaml needed the same trick for the same reason a decade earlier, which suggests the gap is a
property of *-only type systems rather than of TypeScript.
Not retrofittable — immutable values. TC39 withdrew Records and Tuples in April 2025;
readonly is erased with the rest of the types, and Object.freeze is shallow. This is the wall,
and it is made of a governance decision rather than a technical one.
The finding
A paradigm can be adopted at four different depths, and the depth is set by decisions the language took long before anyone tried. clojure and haskell chose functional and paid for it in the data model and the type system respectively. TypeScript chose “JavaScript with syntax for types” and gets functional programming as a style with excellent editor support, which is a real thing and is not the same thing.
The corpus’s older reading — that patterns are language features that have not arrived yet (design-patterns) — has a sibling here. Whole paradigms can arrive as libraries too, and they arrive incomplete in a way the library documentation does not advertise. effect‘s homepage sells reliability, not purity, and on this reading that is honest positioning rather than marketing drift.
Related
haskell · clojure · ocaml · elixir · fsharp · typescript · effect · fp-ts · lightweight-hkt · records-and-tuples · type-system · evaluation-strategy · programming-language · synthesis