vela
A small, fast, statically typed language that compiles straight to native x86-64 and ARM64 executables — no VM, no libc, no linker.
use std/io
struct Point {
x: Float,
y: Float,
}
fn Point.length(self) -> Float {
return (self.x * self.x + self.y * self.y).sqrt()
}
fn main() {
let p = Point{ x: 3.0, y: 4.0 }
io.println("|{p}| = {p.length()}")
}
Why
Simple
The whole language is one document. Four primitive types, one reference model, no traits, no macros, no lifetimes, no implicit conversions.
Fast
About 33,000 lines per second, source to executable. A hello-world binary is 18 KB, starts in under a millisecond, and makes three syscalls before main.
Expressive
Closures, generics, sum types, pattern matching, string interpolation, and errors as values.
Cohesive
The collector, the collections, the formatter and the vela command are all written in Vela. There is no privileged layer you cannot read.
Install
curl -fsSL https://github.com/NT9712/vela/releases/latest/download/vela-1.1.0-linux-x86_64.tar.gz | tar xz
cd vela-1.1.0-linux-x86_64 && ./install.sh ~/.local
export PATH="$HOME/.local/bin:$PATH"
vela new hello && cd hello && vela run
hello from hello
A taste
use std/io
use std/fs
struct User {
name: Str,
age: Int,
}
enum Shape {
Circle(Float),
Rect(Float, Float),
Empty,
}
fn area(s: Shape) -> Float {
return match s {
Shape.Circle(r) => 3.14159 * r * r,
Shape.Rect(w, h) => w * h,
Shape.Empty => 0.0,
}
}
fn load(path: Str) -> !Str {
let text = fs.read_file(path)? // `?` propagates the error
if len(text) == 0 {
return err("{path} is empty")
}
return ok(text)
}
fn largest[T](xs: [T]) -> ?T { // generics, monomorphised
if len(xs) == 0 {
return nil
}
let mut best = xs[0]
for x in xs {
if x > best {
best = x
}
}
return best
}
fn report(users: [User]) {
let names = users.map(|u| u.name) // closures, inference
let oldest = largest(users.map(|u| u.age)) ?? 0
io.println("{names.join(", ")} — oldest {oldest}")
io.println("a circle of radius 2 covers {area(Shape.Circle(2.0))}")
}
Diagnostics are the product
A compiler that only says no wastes your time.
error: cannot add `Str` and `Int`
--> demo.vela:8:18
|
8 | let result = name + age
| ^^^^^^^^^^
= note: expected `Str + Str`
= note: found `Str + Int`
= note: help: convert the right side with `str(x)`
What is actually here
| part | language | lines |
|---|---|---|
| bootstrap compiler, x86-64 and ARM64 backends | C | 12,000 |
| runtime: allocator, collector, strings, collections | Vela | 2,900 |
| standard library: io, fs, os, net, json, math, … | Vela | 2,050 |
| toolchain: formatter, docs, CLI, language server | Vela | 2,600 |
| tests | Vela + shell | 950 |
| documentation and specification | Markdown | 3,100 |
63 test groups: golden output, diagnostics, unit tests, formatter idempotency, the whole toolchain end to end, the language server, release packaging, a regression corpus and randomised fuzzing.
Two targets, no cross toolchain
The compiler encodes the instructions and writes the ELF itself, so
cross-compiling needs nothing installed beyond velac.
vela build --target arm64
file build/hello-arm64
build/hello-arm64: ELF 64-bit LSB executable, ARM aarch64, statically linked
Honest limits
- Linux only. Two architectures, x86-64 and ARM64, both ELF64.
- Single-threaded.
std/processgives parallelism through child processes. - Not self-hosted. The toolchain is Vela; the compiler is still C. The bootstrap page says exactly what is and is not, and what remains.