Compact surface that lowers to Rust. Prefer the tutorial for a guided tour.
name(args) = expr, |x| …, holes / trailing blocks / .field / .m() (examples/closures)x := valueint, str, float, …)type T = { … } with field defaultstype Color = | Red | Custom(int, int, int) + match (string arms too, #101)impl Type = { … }trait / impl Trait for Type; literal/simple default bodiesshape → generated traits + structural calls (examples/shapes)id(x: T)); <> pins and applies. Operators / unique methods on T infer bounds (examples/generics_implicit, examples/shapes_generic)while, for … in (vec MVP), loop, break / continue, value break expr; chained else if (#117, examples/loops)vec<T> from new/push/[1.0, 2.0]; indexing xs[i] / xs[i] = v (#119 / #120, examples/vec_ops)int widens to float in a checking position; postfix as float / as int; unary - on float stays float (#112 / #113). Prelude exp/sin/cos/tanh/sqrt (#115, examples/math)rust = true deps, including local path = "…" (#105); typed extern rust crate { … } / .crpi sidecars (#116, examples/path_dep); use serde_json { … } (or use rust.…)!, throw, catch → Result<T, CrispError>use of functions and types emits crate:: (examples/nested_math, examples/nested_types)test, test_compile_fail; names are unique per module (#102)async, await, extern "C"Comments: -- and nested {- -}. Interpolation: "hello {name}". Exponentiation: **.
Short, copyable patterns. Guided tour: tutorial.
type ServerConfig = {
host: str = "127.0.0.1"
port: uint = 9000
}
pub main() = {
cfg := ServerConfig { port: 3000 }
log("host={cfg.host} port={cfg.port}")
}
type Color =
| Red
| Custom(int, int, int)
describe(c) = match c {
Color.Red -> "red"
Color.Custom(r, g, b) -> "rgb({r},{g},{b})"
}
apply(f, x) = f(x)
double(n) = n * 2
pub main() = {
inc := |x| x + 1
print(apply(double, 21))
print(apply(_ * 2, 21))
print(inc(41))
}
apply(f, x) = f(x)
run(f) = f(21)
label(g, p) = g(p)
type Person = { name: str }
type Vec2 = {
x: float
y: float
}
impl Vec2 = {
new(x, y) = Vec2 {
x: x
y: y
}
magnitude(self) = (self.x ** 2.0 + self.y ** 2.0) ** 0.5
}
pub main() = {
print(run { |x| x * 2 })
print(label(.name, Person { name: "Ada" }))
print(apply(.magnitude(), Vec2.new(3.0, 4.0)))
}
trait Show = { show(self) -> str }
impl Show for Point = {
show(self) = "({self.x},{self.y})"
}
label(x: T) = x.show()
shape HasPosition = {
x: float
y: float
}
distance(a: HasPosition, b: HasPosition) -> float = {
dx := a.x - b.x
dy := a.y - b.y
dx * dx + dy * dy
}
type Pair = { left: A, right: B }
id(x: T) = x
first(p: Pair<A, B>) = p.left
trait Wrapper = { unwrap(self) -> T }
impl Wrapper for IntBox = {
unwrap(self) = self.value
}
shape HasPosition = { x: T, y: T }
distance(a: HasPosition<T>, b: HasPosition<T>) = {
dx := a.x - b.x
dy := a.y - b.y
dx * dx + dy * dy
}
sum_vec(xs) = {
total mut:= 0
for x in xs {
total = total + x
}
total
}
n mut:= 5
loop {
if n == 0 then break n
n = n - 1
}
use serde_json { from_str, to_string }
pub main() = {
v := from_str("[1, true]")
print(to_string(v))
}
test "greet works" = {
assert_eq(greet("world"), "hello world")
}
test_compile_fail "unknown" = {
definitely_not_a_builtin()
}
pub main() = async {
sleep_ms(1)
print("async-ok")
}