# Coalton, a statically typed Lisp that keeps the REPL

> Coalton is a statically typed functional language that compiles into Common Lisp, so types are checked at compile time while the interactive debugging and REPL workflow stay intact. It is used in production for defense and quantum computing software, but it has not reached 1.0 and is tested on only three Lisp implementations.

**coalton-lang/coalton** — Coalton is an efficient, statically typed functional programming language that supercharges Common Lisp.

- Repository: https://github.com/coalton-lang/coalton
- Website: https://coalton-lang.github.io/
- Stars: 1,788 · Forks: 113
- Language: Common Lisp
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/coalton-lang-coalton

## Types in the language, Common Lisp underneath

Coalton is a statically typed functional programming language that integrates directly into Common Lisp, and that second half is what makes it interesting. It is not a separate implementation with its own runtime, it is a compiler that produces Common Lisp code, with the type system, algebraic data types and pattern matching added on top.

The mechanics of that integration are visible in the README's first example. A package is defined with the standard defpackage form, using the coalton and coalton-prelude packages, and the compiler is activated by putting a named readtable in place with (named-readtables:in-readtable coalton:coalton). From that point the forms inside (coalton-toplevel...) are Coalton forms rather than Common Lisp ones.

The type system shows up in a declare form that looks nothing like Common Lisp type declarations. The example declares (declare diff (Num:t => sym:Symbol * Expr:t -> Expr:t)), which is a type-class-constrained polymorphic signature: the function is generic in:t, requires that:t be a Num, and the argument type is the algebraic type Expr:t. The same example then defines a parametric algebraic data type, a define-type form for Expr with constructors EConst, EVar, E+ and E*, where the EConst constructor carries the:t parameter and EVar carries a Common Lisp symbol type written as sym:Symbol.

The compiler's output keeps the Common Lisp runtime conventions. A Coalton value prints as a Common Lisp object with a reader prefix, so a computed expression appears as #.(E+ #.(E* #.(ECONST 1) #.(EVAR |t|))...), and the type of a definition is echoed in the REPL as a Haskell-style signature, SQUARE:: ∀ A. ((EXPR A) → (EXPR A)).

## Errors are compile-time, and they carry a source location

The README's argument for this design is that type errors are discovered at compile time and printed without sacrificing Common Lisp's interactive debugging facilities. The second half of that claim is the unusual part, since most statically typed languages trade the REPL for the checker.

The error output shows what that means. A call mixing a rational and a float inside the same expression produces:

```lisp
error: Type mismatch
  --> repl:1:32
   |
 1 |  (coalton (d/dt (E+ (EConst 1/2) (EConst 0.5))))
   |                                  ^^^^^^^^^^^^ Expected type '(EXPR FRACTION)' but got '(EXPR F32)'
```

The message names the expected type and the actual type, points at the offending span with a caret, and gives a location that works for code typed in the REPL as well as for code in a file. The location format reproduces the source line and puts a caret under the span, which is a deliberate choice to make compiler errors in a dynamic-looking environment easier to read.

The REPL experience is the same story from the other side. A Coalton form can be evaluated in the REPL and its value printed with the standard Common Lisp printer, so you can build a piece of a typed program one form at a time, watch the inferred type come back after each definition, and still drop into the debugger when something goes wrong at runtime. The example even notes that the identifier t is usable because Coalton does not import the Common Lisp symbol cl:t, which is the kind of detail that only matters when two languages share a namespace.

## Installing through Quicklisp, and testing it yourself

The setup path assumes a working Common Lisp toolchain. The README asks you to install SBCL, with a Homebrew command given for macOS, and to install Quicklisp following its own instructions, noting that the step involving gpg is not needed. After that you have a quicklisp folder, which is where the repository is meant to go.

Installation is then a clone into a directory your Lisp can see, the example given being ~/quicklisp/local-projects/. From there, you either load it interactively with (ql:quickload :coalton), or add #:coalton to the :depends-on list in your system definition.

Running the test suite is a two step affair, and the README is precise about it. You compile the tests with (ql:quickload :coalton/tests) and then run them with (asdf:test-system :coalton). There is one dependency you need to know about in advance: on SBCL the suite needs GNU MPFR to run the Big-Float tests. If you do not want to install it, there is a switch, (pushnew :coalton-portable-bigfloat *features*) before loading Coalton, which uses the portable Big-Float implementation instead.

The Makefile shows how the same thing is run in batch mode, which is what CI does. It invokes SBCL with --noinform --no-userinit --no-sysinit --non-interactive, points CL_SOURCE_REGISTRY at the repository root so ASDF can find the local systems without installing anything, and then loads and tests :coalton/tests and loads the small-coalton-programs system. There are three variants: test, test-safe which adds (sb-ext:restrict-compiler-policy 'safety 3), and test-release which sets COALTON_ENV=release. The safe variant is the interesting one, because it exercises the same code under a stricter SBCL compiler policy, which is where portability problems tend to show up.

## The standard library ships with the compiler, and two optional libraries do not

The repository contains the Coalton compiler source under src/ and the standard library under library/. Two further libraries are present but not loaded by default, and the README names both. coalton/xmath is for extended mathematics, and coalton/threads is for threads, synchronization and parallel computation, with the caveat that it is SBCL only.

That SBCL restriction is the clearest signal in the project about where the effort goes. Portable parallel primitives in a typed Lisp that compiles down to Common Lisp are a hard problem, and rather than pretend otherwise the project gates the feature on one implementation. The examples/ directory makes the same point from the other side: there is a parallel-numerics/ example, alongside a raytrace/ example, a fractal/ example, a quil-coalton/ example implementing a simple Quil parser with parser combinators, and an implementation of Jones's Typing Haskell in Haskell under thih/.

The Typing Haskell in Haskell example is worth pausing on. Having it in the examples directory puts the type system to work on a non-trivial program. The small-coalton-programs/ directory holds the pedagogical programs, and the Makefile loads that system as part of the test run, so the examples are checked in CI rather than being decorative.

Documentation is extensive and lives in the docs/ directory, with the manual published at coalton-lang.github.io/manual/, the standard library reference at coalton-lang.github.io/reference/, and a Whirlwind Tour that the README suggests as the starting point. The Makefile can regenerate the standard library reference from the source with coalton/doc:write-stdlib-documentation-to-file, and a web-docs target writes it in a Hugo backend format for the project website.

## Not 1.0 yet, and tested on three implementations only

The README opens the Getting Started section with a warning, and it is the most important thing to know before you commit. Coalton has not reached 1.0, which means that from time to time you may have a substandard user experience. The project aims to be ANSI-conforming but is currently only tested on recent versions of SBCL, Allegro CL and Clozure CL. A second warning notes that the version of Coalton available through Quicklisp may not be up to date.

Those two statements define the risk profile. The compiler is young, so behaviour around error messages, edge cases and performance characteristics can shift, and only three implementations are covered, so a port to another Common Lisp is on you. The Quicklisp lag means the version you get from the standard installation route may lag the repository, which is why the README also tells you to clone the repository into a directory your Lisp can see, and that is the route to take if you want the current code.

The development signal is otherwise healthy. The last push was on 2026-10-16, days before this article was written, and the recent release tags are mine-v0.1.6 from 2026-05-14, mine-v0.1.5 from 2026-05-06 and mine-v0.1.4 from 2026-04-29, with the mine/ directory at the repository root holding that tooling.

The project also says it is used in production to build defense and quantum computing software, and links to a write-up of a quantum compiler built with it. The contributing section asks for bug reports, fixes, small example programs and user experience troubles, and says contributions are especially welcome as the project stabilizes toward 1.0. The licence is MIT, with LICENSE.txt in the repository root and a CITATION.cff file for citation metadata.

## Conclusion

Coalton suits Common Lisp developers who want static types and algebraic data types without giving up the REPL, and it suits teams that already have Lisp infrastructure and a reason to keep the language, such as the production defense and quantum computing work the project mentions. It is the wrong choice for a project that needs a 1.0 stability guarantee, since the README warns that the user experience may be substandard at times, and it is the wrong choice if you need to run on more than three Lisp implementations, because testing is limited to SBCL, Allegro CL and Clozure CL. Before adopting it, check the version in your Quicklisp installation against the repository, since the README warns the Quicklisp copy may not be current, and decide about GNU MPFR early, because the test suite needs it for the Big-Float tests unless you push the coalton-portable-bigfloat feature.

## FAQ

### How do I install Coalton?

Install SBCL and Quicklisp, then clone the repository into a directory your Lisp can see such as ~/quicklisp/local-projects/. Load it with (ql:quickload :coalton), or add #:coalton to the :depends-on list in your system definition.

### Does Coalton replace Common Lisp or extend it?

It extends it. Coalton compiles into Common Lisp and is activated by putting its readtable in place with (named-readtables:in-readtable coalton:coalton), after which Coalton forms can be written inside (coalton-toplevel ...) and evaluated in the REPL.

### Which Common Lisp implementations does Coalton support?

The README says the project aims to be ANSI-conforming but is currently only tested on recent versions of SBCL, Allegro CL and Clozure CL. The optional coalton/threads library for parallelism is SBCL only.

### How do I run the Coalton test suite?

Compile with (ql:quickload :coalton/tests) and run with (asdf:test-system :coalton). On SBCL the Big-Float tests need GNU MPFR, unless you push :coalton-portable-bigfloat onto *features* before loading Coalton to use the portable implementation.

### Where do I find the Coalton documentation?

The README points to the Whirlwind Tour of Coalton in the docs directory, the language manual and the standard library reference on the project website, the examples directory, and an introductory blog post. The standard library reference can be regenerated from the source using the docs target in the Makefile.

## Sources

- [coalton-lang/coalton on GitHub](https://github.com/coalton-lang/coalton)
- [License: MIT](https://github.com/coalton-lang/coalton/blob/main/LICENSE)
- [Project website](https://coalton-lang.github.io/)
- [README](https://github.com/coalton-lang/coalton/blob/main/README.md)
- [Releases](https://github.com/coalton-lang/coalton/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/coalton-lang-coalton
