# Carp: a statically typed Lisp that compiles to C without a garbage collector

> Carp is a research-stage Lisp for games, sound and visualisation, where memory is managed by compile-time ownership tracking instead of a runtime collector. The README warns against using it for anything important, and that warning shapes how the project should be read.

**carp-lang/Carp** — A statically typed lisp, without a GC, for real-time applications.

- Repository: https://github.com/carp-lang/Carp
- Stars: 6,058 · Forks: 188
- Language: Haskell
- License: Apache-2.0
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/carp-lang-carp

## What Carp is trying to fix in the Lisp family

Most Lisps buy their flexibility with a runtime: a garbage collector, often a VM or an interpreter loop, and allocation behaviour the programmer does not directly control. Carp takes the syntax and macro system of a Lisp and removes that runtime layer. The README describes the goal as a language for "interactive and performance sensitive use cases like games, sound synthesis and visualizations", and lists automatic and deterministic memory management with no garbage collector or VM as the first key feature. The audience is therefore narrow and specific: people who want Lisp macros and a REPL but who cannot accept a collector pause or a managed heap. The README is equally direct about maturity, carrying a warning that this is a research project and that information in it may become outdated and misleading without explanation, with the instruction not to use it for anything important yet. That sentence is the most important line in the repository for anyone making an adoption decision.

## Ownership tracking instead of a garbage collector

The mechanism the README names is ownership tracking, which it says enables a functional programming style while still mutating cache-friendly data structures underneath. Allocation and copying are explicit, and the project claims no hidden performance penalties. Types are inferred and static, so the compiler has the information needed to decide when a value can be freed or reused rather than waiting for a collector to discover it. This is a compile-time discipline, not a runtime service. The practical consequence is that a Carp program's memory behaviour is determined before it runs. The practical cost is that the programmer carries obligations the compiler can check but cannot silently absorb. The README does not describe the ownership rules themselves; that is left to docs/LanguageGuide.md, which the README points at for syntax and semantics. Anyone evaluating Carp for a latency-sensitive loop should read that guide before assuming the model matches Rust's borrow checker, because the README does not make that comparison.

## Compiling to C and calling into existing code

Carp does not ship a bytecode VM. It emits C, which is why straightforward integration with existing C code appears in the key features list, and why the repository contains a headerparse directory alongside src and app. The example in the README loads SDL through a load-and-use form and then builds a window with SDLApp.create and SDLApp.run-with-callbacks, so the standard path to a graphical program runs through an existing C library rather than a Carp-native toolkit. That is a real advantage for anyone with a C codebase or a C library they already trust. It is also a constraint: the ecosystem of libraries is the C ecosystem, and the bindings available are the ones that exist. The examples directory includes glfw.carp and minimal_sdl.carp, which is consistent with a graphics story built on C libraries rather than a bespoke framework.

## Building the compiler and running your first program

The README does not print install commands. It states that the Compiler Manual in docs/Manual.md covers how to install and use the compiler, and that docs/HowToRunCode.md explains how to run Carp code. The repository layout shows the compiler is a Haskell program: CarpHask.cabal, stack.yaml, Setup.hs and default.nix sit at the top level, with sources under src and app. The Stack file is the build entry point the repository layout points at, so the command below is the one those files imply; confirm the exact invocation in docs/Manual.md rather than treating this as the documented procedure.

```bash
stack build
```

That builds the compiler from source. Expect a Haskell toolchain plus a C compiler, since Carp emits C and the examples link against C libraries. The README's own example is the smallest complete Carp program it shows, and it is the honest starting point for a first real use because it exercises loading a C library, defining functions and running a callback loop. It defines tick and draw, then creates an SDL window titled "The Minimalistic Color Generator" at 400 by 300 and runs it until escape is pressed.

```clojure
(load-and-use SDL)

(defn tick [state]
  (+ state 10))

(defn draw [app rend state]
  (bg rend &(rgb (/ @state 2) (/ @state 3) (/ @state 4))))

(defn main []
  (let [app (SDLApp.create "The Minimalistic Color Generator" 400 300)
        state 0]
    (SDLApp.run-with-callbacks &app SDLApp.quit-on-esc tick draw state)))
```

The draw function reads the current state through @ and writes a background colour derived from it, while tick advances the state by ten each frame. Running this requires SDL to be present and the compiler to be on your path; docs/HowToRunCode.md is the document the README designates for that workflow. If the window opens and the background colour shifts as the state climbs, the toolchain, the C interop and the callback model are all working. If it does not, the failure is more likely in the SDL binding or the build than in the language itself.

## The research-project warning is not boilerplate

Two facts sit next to each other in the repository history. v0.5.5 was released on 2022-04-22, and v0.6.0 followed on 2026-03-28, a gap of roughly four years between minor releases. The last push to the repository was on 2026-09-11, so work has continued, but a release cadence with a four-year hole in it tells you something about how the project is resourced. Combine that with the README's own instruction not to use it for anything important yet, and the correct reading is that Carp is a language you evaluate, not one you standardise on. The wrong tool for a team that needs a documented upgrade path, a deprecation policy or a vendor to call. Also wrong for anyone who wants the library breadth of a mainstream language: the C interop is the ecosystem, and if the C library you need has no binding, you are writing one.

## Where Carp sits next to other small languages

The related searches around this project point at Fennel and Roc, and both comparisons are instructive. Fennel is a Lisp that compiles to Lua, so it inherits Lua's garbage collector and its runtime; Carp's whole premise is the opposite, replacing the collector with compile-time ownership. Roc is a functional language with its own runtime and platform model rather than a Lisp macro system, and it does not claim C as its compilation target in the way Carp does. Neither is a drop-in substitute. If your reason for looking at Carp is the Lisp syntax and a REPL, Fennel will get you there faster and on a runtime you already understand. If your reason is deterministic memory without a collector, Carp is the one of the three making that specific promise, and the README is candid that the promise is still under research.

## Licence, upgrades and what they cost you

Carp is licensed under Apache-2.0, and the README's licence section carries the standard warranty disclaimer and limitation of liability language. One detail worth knowing before you vendor the source: the regular expression implementation in src/carp_regex.h is Copyright (C) 1994-2017 Lua.org, PUC-Rio, under the MIT license, with details in the separate LUA_LICENSE file. So the repository is not uniform in licensing, even though the project as a whole is Apache-2.0. That is a fact to hand to whoever reviews dependencies, not a legal opinion. On upgrades, the CHANGELOG.md at the top level is the record to read before moving from v0.5.5 to v0.6.0, and the README's own warning about information becoming outdated without explanation is a fair description of the risk in a four-year release gap.

## Conclusion

Adopt Carp if you are exploring a Lisp with inferred static types, explicit allocation and C interop, and you accept the README's own warning that it is a research project not to be used for anything important. Do not adopt it for production services or anything with a support contract. Before writing code, read docs/Manual.md for the build steps and docs/HowToRunCode.md for the run workflow, and check the CHANGELOG for what v0.6.0 changed relative to v0.5.5.

## FAQ

### Does Carp have a garbage collector?

No. The README lists automatic and deterministic memory management with no garbage collector or VM as the first key feature, and describes ownership tracking as the mechanism that lets a functional style coexist with mutation of cache-friendly data structures.

### Is Carp ready for production use?

The README carries an explicit warning that Carp is a research project, that information in it may become outdated and misleading without explanation, and that it should not be used for anything important yet.

### What does Carp compile to?

Carp emits C, and the README lists straightforward integration with existing C code as a key feature. The README's example loads SDL and builds an application through SDLApp.create and SDLApp.run-with-callbacks.

### Where are the installation instructions for Carp?

The README points to docs/Manual.md as the Compiler Manual covering how to install and use the compiler, and to docs/HowToRunCode.md for instructions on running Carp code.

## Sources

- [carp-lang/Carp on GitHub](https://github.com/carp-lang/Carp)
- [Issues](https://github.com/carp-lang/Carp/issues)
- [License: Apache-2.0](https://github.com/carp-lang/Carp/blob/master/LICENSE)
- [README](https://github.com/carp-lang/Carp/blob/master/README.md)
- [Releases](https://github.com/carp-lang/Carp/releases)

---

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