ML & FP Family — Tier 3 Index
ML & FP Languages — Tier 3 Index
- Type: language-family-index
- Family: ML descendants + extended functional programming
- Languages catalogued: 21
- Last updated: 2026-05-07
Family overview
The ML family began with Robin Milner’s Meta Language for the LCF theorem prover (1973) and gave the world Hindley-Milner type inference, algebraic data types, pattern matching, and parametric polymorphism — the toolkit every modern statically-typed FP language now uses. Branches diverged into Standard ML (academic, eagerly evaluated), the Caml lineage (OCaml, F#), Haskell (lazy, pure), and a long tail of research/teaching languages exploring uniqueness types (Clean), dependent types (Idris, ATS), algebraic effects (Eff, Koka), and content-addressed code (Unison). You’ll encounter ML-family languages in compiler internals, theorem provers, financial DSLs, formal-methods tooling, and increasingly in front-end web (Elm, PureScript, ReScript). The unifying thread is let the type system catch real bugs at compile time without ceremony — most ML descendants get away with no annotations through inference.
In our deep library
- haskell — Pure lazy FP with type classes; the de facto “research-grade” FP language since 1990.
- ocaml — Strict ML with objects, modules, and a fast native compiler; powers Jane Street, Coq, Flow.
- fsharp — OCaml on .NET with computation expressions; Microsoft’s official FP language.
- roc — Modern strict pure FP with platform-based effects; Elm-influenced syntax, no GC by default.
- gleam — Statically-typed BEAM language with ML-like syntax; FP for Erlang/OTP.
- idris — Dependently-typed FP with quantitative type theory (Idris 2 since 2020).
Tier 3 — the family
| Language | First release | Status (2026) | Niche / use case | Why it matters | Source |
|---|---|---|---|---|---|
| Standard ML (SML) | 1983 (DefSML 1990, revised 1997) | Active (academic) | Compiler courses, formal semantics | The first language with a complete formal definition; SML/NJ, MLton, Poly/ML and MLKit are still maintained | https://smlfamily.github.io |
| Caml Light | 1990 | Defunct (superseded by OCaml ~1996) | Historical / teaching | INRIA’s bytecode interpreter; INRIA dropped it for OCaml — still used in some French CS curricula | https://caml.inria.fr/caml-light/ |
| Mercury | 1995 | Active (slow-moving) | Logic + functional + types | Prolog descendant with strong static modes/types/determinism; used by Prince XML and YesLogic | https://mercurylang.org |
| Curry | 1996 | Active (academic) | Functional + logic hybrid | Haskell syntax with non-deterministic search and free variables; PAKCS and KiCS2 are live implementations | https://www.curry-lang.org |
| Clean | 1987 | Active | Pure FP with uniqueness types | Pioneered uniqueness/linear-type-style ownership in 1987 — direct intellectual ancestor of Rust’s borrow checker | https://clean.cs.ru.nl |
| PureScript | 2013 | Active | Haskell-shaped language for JS | Strict by default (vs Haskell’s laziness); row polymorphism for records; popular for Halogen/React-style frontends | https://www.purescript.org |
| Elm | 2012 | Active (slow release cadence) | Pure FP for the frontend | ”No runtime exceptions” — designed-out failure modes; Roc’s syntax descends directly from it | https://elm-lang.org |
| ReScript | 2020 (renamed from BuckleScript) | Active | OCaml-shaped JS/TS replacement | Compiles a curly-brace-flavored OCaml to readable JS; Facebook origins; ReasonML’s modern incarnation | https://rescript-lang.org |
| Frege | 2011 | Maintenance | Haskell-on-JVM | Implements Haskell 2010 with JVM interop; still works but development largely stalled | https://github.com/Frege/frege |
| Eta | 2017 | Defunct (last release 2019) | Haskell-on-JVM via GHC fork | Forked GHC 7.10 to target JVM; ambitious but ran out of funding; instructive cautionary tale for compiler forks | https://eta-lang.org |
| Idris 1 | 2009 | Superseded | Predecessor to Idris 2 | Pioneered self-hosting dependently-typed compilation; Idris 2 (covered in deep library) replaces it on Chez backend | https://www.idris-lang.org/old/ |
| ATS | 2007 | Active (research) | Systems programming with dependent + linear types | Compiles to C; combines proof obligations with low-level pointer arithmetic — used in OS and embedded research | https://www.ats-lang.org |
| Granule | 2018 | Active (research) | Graded modal types | Tracks resource usage in the type system (linearity, security, sensitivity) via a graded modality | https://granule-project.github.io |
| Helium | 2002 | Maintenance | Haskell teaching subset | Stripped-down Haskell with dramatically improved error messages — designed for first-year FP courses at Utrecht | https://www.cs.uu.nl/wiki/Helium |
| Hope | 1980 | Defunct (historical) | Early FP teaching language | Edinburgh-era language that introduced algebraic data types as a primary feature; precursor to Miranda/Haskell | https://en.wikipedia.org/wiki/Hope_(programming_language) |
| Miranda | 1985 | Defunct (commercial) | Lazy FP precursor to Haskell | David Turner’s commercial lazy FP; its design directly motivated the 1987 Haskell committee | https://www.cs.kent.ac.uk/people/staff/dat/miranda/ |
| Eff | 2012 | Active (research) | Algebraic effects laboratory | Andrej Bauer’s effect-handler language; predates Koka and influenced OCaml 5’s effect handlers | https://www.eff-lang.org |
| Koka | 2012 | Active (Microsoft Research) | Algebraic effects + ref counting | Daan Leijen’s effect-typed language with Perceus reference counting; effect rows tracked per function | https://koka-lang.org |
| Unison | 2020 (1.0) | Active and growing | Content-addressed FP for distributed systems | Functions stored by hash, not name — eliminates dependency conflicts; novel “abilities” effect system; Cloud platform shipped 2024 | https://www.unison-lang.org |
| Lean 4 | 2021 | Active and growing | Theorem prover + general-purpose FP | Self-hosted dependently-typed language; mathlib4 community is the largest formalized math project ever | https://lean-lang.org |
| Haxe | 2005 | Active | Cross-platform FP-leaning language | Compiles to JS, C++, C#, Java, Python, Lua, HashLink; FP-flavored with macros; backbone of Dead Cells, Northgard, Papers Please | https://haxe.org |
Notes adjacent to the table (context, not full rows)
- Liquid Haskell — refinement-type extension to GHC; covered in the deep haskell note. Mentioned here because it represents the “refinement types as a plugin” lineage that ATS/Granule explore as first-class language features.
- Squiggol / Bird-Meertens formalism — not a language but a calculational notation for deriving FP programs; foundational to Haskell’s idioms (
fold,map,scanalgebra) and worth knowing if you’re reading 80s/90s FP papers. - Disciple — ML-family research language from Ben Lippmeier (DDC compiler) with explicit effect and region annotations; influential on later effect-system designs but not in active production use.
Notable threads
Strict vs lazy split. Standard ML, OCaml, F#, Roc, Gleam, Elm, PureScript, and most Tier-3 ML descendants are strict (eager evaluation). Haskell, Miranda, and Frege are lazy. The lazy camp earned reputation for elegance (infinite lists, Hughes’ “Why FP Matters” stream-fusion arguments) but laziness exacts a cost in space-leak debugging and predictable performance — every strict ML-family language ships with explicit lazy / thunk types when laziness is wanted, and that’s increasingly the consensus design.
Effect systems as the new frontier. The 2010s-2020s wave of FP research has converged on effect typing rather than monadic-IO-as-default. Eff and Koka pioneered handlers as language primitives; Unison’s “abilities” generalize the same idea; OCaml 5 (2022) and Roc both ship effect handlers as part of the runtime. This is the most significant shift in FP language design since type classes — it lets you write generic code that abstracts over IO/state/exceptions without the monad-transformer ergonomics tax. Watch this space: Haskell’s effectful, Scala’s gears, and Roc’s platform model are all converging on similar shapes.
Linearity, uniqueness, and the road to Rust. Clean (1987) introduced uniqueness types — the constraint that a value has exactly one reference and can therefore be mutated in place safely. ATS extended this with linear types for systems programming. Granule generalized it to graded modalities. Rust’s borrow checker is the same idea repackaged for an imperative-feeling syntax with no GC. The intellectual lineage Clean → ATS → Rust → linear-types-Haskell (2020) is one of the more striking cross-paradigm transfers in language history.
Frontend web as ML’s beachhead. Elm (2012), PureScript (2013), ReScript (2020), and increasingly Roc target the browser. The pitch is uniform: Hindley-Milner inference catches the kind of type errors that JavaScript’s undefined is not a function would have shipped to production. None has displaced TypeScript at the volume layer — but each owns a corner where teams are willing to trade ecosystem size for type safety. Worth tracking: Roc’s bet is that the same value proposition extends to backend platforms, not just the browser.
Citations
- Wikipedia — ML (programming language): https://en.wikipedia.org/wiki/ML_(programming_language)
- Wikipedia — Standard ML: https://en.wikipedia.org/wiki/Standard_ML
- Wikipedia — List of functional programming languages: https://en.wikipedia.org/wiki/Category:Functional_languages
- “A History of Haskell: Being Lazy with Class” (Hudak, Hughes, Peyton Jones, Wadler — HOPL-III 2007): https://www.microsoft.com/en-us/research/wp-content/uploads/2016/07/history.pdf
- “Algebraic Effects for the Rest of Us” (Dan Abramov, 2019): https://overreacted.io/algebraic-effects-for-the-rest-of-us/
- Koka language paper — “Algebraic Effects for Functional Programming”: https://www.microsoft.com/en-us/research/publication/algebraic-effects-for-functional-programming/
- Unison docs — content-addressed code: https://www.unison-lang.org/docs/
- See also: haskell, ocaml, fsharp, roc, gleam, idris