plum v0.0.27
Plum is a small, statically typed, compiled language.
Plum has a website, and the compiler wrote most of it.
plumlang.org
Prose, a full API reference, and search: plumlang.org.
The reference on it is not written by hand and not checked in. It is
generated by the compiler at that commit, from the standard library's
own source, so it cannot describe a library that no longer exists. The
prose pages are generated from the Markdown in the repository, so each
document has one copy and reads correctly in both places.
plum doc
The same command that produced the reference works on your code:
plum doc my-project -o docs # Markdown, one page per module
plum doc my-project -o docs --html # a browsable site, with searchThe HTML output is self-contained: no build step, no network, no CDN.
Open it from a folder on disk and search still works, because the index
is a script the page loads rather than a file it fetches.
Documentation comes from /// comments. They are kept as trivia on
the token stream, so they attach to declarations without appearing in
the AST and nothing downstream had to learn about them. plum lsp hover
shows them too.
The standard library documents itself
Every public declaration now carries documentation, written on the
declaration rather than in a list somewhere: 335 declarations, none
undocumented. It goes through the same code path your project uses,
and bootstrap/check-docs fails if docs/stdlib/ falls behind the
compiler.
The README used to list the library by hand. It was accurate, and
nothing checked it, which is a promise that keeps for exactly as long as
somebody keeps remembering.
plum highlight
plum highlight src/main.plum # Plum source as marked-up HTMLEvery static site generator ships a syntax highlighter, and none of them
ships one for a language this young. The usual answer is to write one: a
keyword list and some regexes, maintained separately, wrong about the
corners. Bitwise operators landed in 0.0.26; that highlighter would
already be wrong about ^.
This is the real lexer instead. It works because the token stream is
lossless, so walking it and wrapping each token in a span gives the file
back with markup, and that has a property no regex highlighter can
claim: strip the tags, undo the escaping, and you get the source back
byte for byte. bootstrap/highlight-check asserts it over 294 files,
including the compiler's own 69KB parser. Code that people copy and
paste cannot be silently corrupted by the thing that coloured it.
Source that does not lex renders plain rather than not at all, so an
illustrative fragment still shows up.
The README is a front door again
It was 1,439 lines. It is now 88. The language tour, the module system,
the tooling and the running instructions moved into their own documents,
published as pages on the site and readable on GitHub.
VISION.md was reconciled with reality while this happened. It still
claimed the compiler was written in Rust, which stopped being true on
2026-08-25.
Also in this release
- The compiler runs its own subprocesses through
Process.runrather
than shelling out, which is one fewer place the toolchain depends on a
Unix shell being present. - A quadratic in
lexer.token_text: it split the whole source into
characters to answer a question about one token. Harmless for its
original caller and ruinous for anything walking the stream. New
token_text_at/trivia_before_attake the split source. 65s to
0.69s on the compiler's own parser. - A closure capture could be offered as a memory-reuse candidate and
released twice. Found by writing a JSON decoder library in Plum. bootstrap/doc-checkandbootstrap/check-doc-namesnow derive their
file lists from what the site publishes, so a new document cannot be
added without its snippets being compiled and its names checked. That
took name checking from two files to ten and immediately found six
unchecked names.