
# Flan
**A statically typed Lisp for native games and interactive development.**
Flan is an experimental, ahead-of-time compiled Lisp for programs that need
predictable memory use and a fast edit–run loop. It combines S-expressions,
static types, explicit ownership, and a development session that can replace a
function in a running program without resetting its state.
It is being built around games, but the interesting part is broader: a compiled
language where the running program remains available for inspection,
experimentation, and small changes.
In practical terms: you get parentheses, a debugger that would like to have a
conversation, and no garbage collector quietly choosing the dramatic moment to
join your frame loop.
## What it has
- Native compilation through LLVM, plus an in-progress direct x86-64 backend.
- C-like data layout: structs, fixed arrays, pointers, slices, and explicit
allocation. There is no garbage collector.
- Owned `Vec` and `Map` containers, plus checked moves and borrowing-oriented
slice operations.
- Generics, algebraic unions, enums, macros, packages, `defer`, and a C FFI.
- Conditions and restarts for recoverable failures and interactive debugging.
- A raylib package and a collection of ported raylib examples.
- Native, WASI, and web build targets. The cross targets are useful but less
complete than the native development workflow.
The project is exploratory software, not a stable language release. Some
features are deliberately refused while their semantics are still undecided;
the compiler aims to say why rather than quietly accepting a partial version.
It has opinions, but at least they arrive as error messages.
## Quick start
Building requires a current OCaml/Dune toolchain, LLVM/Clang, and the native C
toolchain. Raylib is only needed for programs that use the bundled graphics
package.
```sh
dune build
dune exec ./bin/main.exe -- run web/examples/hello.flan
```
To build a standalone native executable:
```sh
dune exec ./bin/main.exe -- build web/examples/hello.flan -o hello
./hello
```
The falling-sand demo uses raylib:
```sh
dune exec ./bin/main.exe -- run sand.flan
```
Once you are iterating regularly, put the built executable on your `PATH` if
you want to use the shorter `flan` commands shown below.
## The live development loop
Start a long-lived development session:
```sh
flan dev sand.flan
```
The program runs normally and publishes a local socket beside the source file.
The bundled Emacs mode can attach to it, evaluate expressions in the live
process, inspect a stopped program, and recompile a top-level function from
the buffer. A body change takes effect on the next call; changing a function's
signature is intentionally rejected. The program keeps its state, which is
especially nice when you have finally arranged the sand into something almost
worth saving.
To set up the mode:
```elisp
(add-to-list 'load-path "~/path/to/flan/emacs")
(require 'flan-mode)
```
Then use `M-x flan` to start and attach, or `C-c C-z` to attach to a
session started in a terminal. The editor workflow is documented in
[emacs/MANUAL.md](emacs/MANUAL.md).
## A small example
```lisp
(defstruct AssetMissing [id i32])
(defn load-asset [id i32] i32
(signal (AssetMissing {.id id}))
100)
(defn asset-or-placeholder [id i32] i32
(restart-case (load-asset id)
(use-placeholder [] -1)))
(defn main [] ()
(handler-bind [(AssetMissing [_] (invoke-restart 'use-placeholder))]
(println (asset-or-placeholder 7))))
```
Here a missing asset signals a typed condition. The handler chooses a restart,
so execution continues with a placeholder instead of requiring error values to
be threaded through every caller. See
[web/examples/restart.flan](web/examples/restart.flan) for a runnable version.
## Commands
Eleven of them, and the four anyone starts with:
```text
flan check