One owner. One way. No surprises.
Singular is a compiled, memory-safe programming language. It's designed to run as fast as C, to be as safe as Rust, and to be much easier to read and learn than either.
What it looks like
struct Item {
String name
Float price
}
fn discount(edit List[Item] items, Float percent) {
for Item item in edit items {
item.price *= 1.0 - percent / 100.0
}
}
fn main() {
List[Item] cart = [Item { name: "book", price: 20.0 }]
discount(edit cart, 10.0)
print("{cart[0].name}: {cart[0].price:.2}")
}
Every name is declared with its type. discount may change the cart, so the call says edit cart.
The idea in one paragraph
Every value has one owner. A function can view what you pass it, which is the default, edit it, or move it (take it for good). edit and move are written at the call site too, so f(x) never changes x, f(edit x) might, and after f(move x) the variable x is gone. You can tell what happens to every variable from the line it's on, and every name is declared with its type, so you can always tell what it is.
Views can't be stored or returned. That means all safety checking happens inside one function at a time, so there are no lifetime annotations, no garbage collector, and no hidden copies.
Design choices at a glance
| Singular | Instead of |
|---|---|
Int score = 0, with const in front for names that never change | let/var and types you have to guess |
No pointers: * only ever means multiply | *p, &x, **, -> |
edit and move written at the call site, with view as the default | Lifetimes, &, &mut, Box, Rc<RefCell<T>> |
Arena[T] + Handle[T] for linked data | Reference-counted pointer graphs |
raises E, try and catch | Exceptions you can't see, or Result plus a "fallible" twin of every helper |
comptime values, [comptime Int N] parameters and comptime if | Macros and build scripts |
| Braces, no semicolons, one formatter | Significant indentation or style debates |
and, or, not, any Trait | &&, ||, !, dyn Trait |
Types UpperCamelCase, values lower_snake_case (enforced) | Guessing what a name refers to |
| Stable error codes with fixes, and JSON output for tools and AI agents | Error text you have to scrape |
Status
Singular is a v0.1 draft. The design is written down, and the compiler is being built in stages.
- Done Parser.
sing checkreads.singfiles and reports syntax errors with stable codes, as text or as JSON. - In progress Interpreter. It will run the example programs and check their output.
- Next Checkers for names, types, ownership and errors, then native code through C, LLVM and Singular's own backend.