Nerve

Your first program

MAIN {
    stdkit::print.stored["Hello, World!", newln];
}
PrintsHello, World!

Syntax in five minutes

1Names are quoted

Variables always sit in single quotes. Types, functions and fields are bare words.

let 'x' := 1000;
2let binds a value

Use let to introduce a value. := infers its type; with =, write the type explicitly.

let 'x' := 1000;
let 'n': int32 = 5;
3Changing says change

Declare a value mut before changing it. change marks an assignment.

let mut 'x' := 1000;
change 'x' = 2000;
4Calls use brackets

Arguments go in [ ], not ( ).

add[1, 2]
5Arithmetic uses words

plus, minus and times are operators. Division and remainder name their rounding, such as div.floor and mod.floor; pow raises to a power.

let 'by3' := ('n' mod.floor 3) == 0;
6Positions start at 1

The first element is position 1, and every position says pos.

return 'xs'[pos 1];
7The newline is outside the string

A string is exactly its characters. The newline is its own piece, newln.

stdkit::print.stored["Hello, World!", newln];
8Ownership at the call site

The caller says whether it lends, gives or copies.

describe[lend 'l']
9A dot narrows

The thing on the left, made more specific: str.utf8, lend.mut, list.length.

if list.length[lend 'xs'] equal_to 0 { fail empty; }
10Comments

# runs to the end of the line.

# like this
11Comparison uses words

equal_to, not_equal, at_most and at_least; only < and > stay symbols.

while 'i' at_most 'limit' {

Core features

Precog

Every overflow and bounds check is proven at compile time — or the program doesn’t build.

Ownership, no GC

Every value has one owner. give, copy and lend say what happens to it.

:= picks the best type

Worked out from the whole program. A value from outside needs its type written.

A dot narrows

str.utf8, lend.mut, list.length, map.ordered — one small rule, everywhere.

Failures in signatures

-> T or fail[name], handled with otherwise.

LLVM backend

Native code, through LLVM.