candela¶
candela is a small statically typed scripting language with Rust-like syntax. It is the scripting language of the Lumen UI framework, and it works just as well on its own.
It began as a fork of keel, a language written by Horace Hoff; candela's compiler, virtual machine and type system are built on that work.
Who it is for¶
candela is for people who want a scripting language that catches mistakes before the program starts. Types are checked at compile time, but you rarely write one down: annotations are optional on variables and function parameters, and the compiler works out the rest. What you get is a language that reads like a script and fails like a compiler.
It suits two jobs in particular. The first is scripting an application: a host program written in Rust can compile candela source, hand it functions to call, and exchange values with it. The second is standalone programs that need a short, predictable start, because you can compile ahead of time and ship a runtime that carries no compiler.
A taste¶
enum Shape {
Square(int),
Rect(int, int),
}
impl Shape {
fn area(self) {
match self {
Square(s) => { return s * s; }
Rect(w, h) => { return w * h; }
}
}
}
fn main() {
let shapes = [Square(3), Rect(2, 5)];
let total = 0;
for shape in shapes {
total += shape.area();
}
print("total area: " + str(total));
}
Enum variants carry payloads and match binds them. An impl block gives a
type methods you call with a dot. Lists are literals and for walks them. Not
one type annotation appears, yet every one of those types is known before the
program starts.
The toolchain¶
Two programs install together. candela is the compiler: it runs source files,
hosts the REPL, and compiles a .cdl source file into a .cdlb bytecode
artifact. candela-vm is the runtime alone, which runs an artifact and links
no parser, compiler or REPL.
The standard library ships beside them as candela source, so every function in
it is readable. lpm, the registry client, installs alongside and fetches the
packages a project depends on.
Editor support comes from candela-lsp, the language server, which runs the
same compiler your build does and reports what it finds as you type.
Diagnostics, hover, completion, an outline, and go to definition come from it,
so every client gets the same answers. Highlighting is the client's own, from
one of two grammars, and editors/ holds five clients:
editors/vscode, for VS Code: a TextMate grammar, with snippets.editors/jetbrains, for the IntelliJ-based IDEs: the same TextMate grammar, which the build reads out of the VS Code extension.editors/zed, for Zed: the tree-sitter grammar, which Zed clones and compiles itself.editors/tree-sitter/nvim, for Neovim: the tree-sitter grammar and its queries, throughnvim-treesitter.editors/tree-sitter/helix, for Helix: the tree-sitter grammar, fetched and built byhx --grammar.
Every one of them can be pointed at a server you built yourself instead of the one on your path.
The two grammars are written separately and do not cover the same syntax, so a
construct may colour in one editor before the other. Install the VS Code
extension from the Marketplace or Open VSX; the rest build from this
repository. Setup for each is in its own README.md, except Neovim and Helix,
which share editors/tree-sitter/README.md.
Where to go next¶
Getting started takes you from nothing to a running program.
- Install: the install script, the Windows package, updates and pinning.
- Hello, world: your first program, line by line.
- Running programs: source, the REPL, artifacts and the command line.
- Projects and packages:
candela.toml, dependencies, the lock file and publishing.
Language is the tour, meant to be read in order.
- Variables and Types.
- Control flow and Functions.
- Methods, Enums, Generics and Collections.
- Error handling, Modules and Macros.
Standard library is the lookup reference: an overview of how the library ships and how to import it, the built-in functions that need no import, and a page for each module.
Reference covers the operators, the
error catalogue, the CLI, the
manifest, and the
.cdlb artifact format.
Integration is for host applications: embedding candela in Rust and calling dynamic C libraries from candela.
Contributing explains how to build the toolchain yourself.
Using candela inside a Lumen application is covered by the Lumen documentation rather than this site; follow the Lumen bindings link in the navigation.