Language Reference
The type system, protocols, macros, and async/concurrency features are work in progress. This reference covers the stable core of the language.
Comments
Literals
Booleans
Numbers
Integer size is inferred from the literal value and sign:
1_234_567 # u32
+1 # i8
-1 # i8
0xFF # u8
+0xFF # i8
0xFfFf # u16
0xFFFF_FFFF # u32
0xFFFF_FFFF_FFFF_FFFF # u64
0o_1234_5670 # octal
0b_0101_1111 # binaryFloats and decimals:
1.0 # f32
1.0e100_000 # f64
1.0d # decimal — cannot mix with floats
1.0d-100 # decimal with negative exponentStrings
Single-quoted, with interpolation and multiline support:
Escape sequences:
'\n' # newline
'\t' # tab
'\\' # backslash
'\'' # single quote
'\x0f' # hex code point
'\u{10_ff_ff}' # Unicode code point
'\${' # literal ${String blocks — no need to escape single quotes, indentation stripped:
Tagged template strings pass raw parts and values to a function:
Raw strings — escape sequences are not processed:
Tagged literals
Postfix function application for readable units:
Collections
# sequences (tuple-optimized when used as such)
[]
[1, 2, 3]
seq 1, 2, 3
# records (compile-time field names)
{}
{foo: 1, bar: 2}
{foo: 1, 'ni na': 2, (key): 3} # computed keys
# dictionaries (runtime keys)
dict {foo: 1, 'bar': 2, (key): 3}
# sets
set 1, 2, 3
ordered_set 3, 2, 1Operators
Arithmetic
-a # unary minus
a + b
a - b
a * b
a / b
a // b # integer divide
a ** b # power
a % b # remainder (sign follows dividend)
a %% b # true modulus (sign follows divisor)
a /% b # divmod — returns [quotient, remainder]Logical
Operands must be bools, returns bool:
Bitwise
~a # not
a & b # and
a ^ b # xor
a >> b # shift right
a << b # shift left
a >>> b # rotate right
a <<< b # rotate leftComparison
Chainable, always returns bool:
Ranges
Spread
Bindings and Pattern Matching
Left-hand binding
Patterns can include guards:
Rest patterns:
String patterns:
Record patterns match partially; sequence patterns match exactly:
Right-hand binding
Capture the result of a multiline expression:
match
Match on structure:
Match with guards:
match foo:
n > 0 and n < 10: 'small positive ${n}'
n > 0: 'large positive ${n}'
even n: 'even number ${n}'
_: 'other'Match on types:
Match on sequence and record structure:
match items:
[]: 'empty'
[x]: 'one element'
[x, y]: 'two elements'
[x, ..rest]: 'head and rest'
match foobar:
{}: 'empty'
{foo: 1}: 'has foo = 1'
{foo: 1, ..rest}: 'has foo = 1 and more'Functions
add = fn a, b:
result = a + b
result
# no args
greet = fn: 'hello'
# default args
greet = fn name='world': 'hello ${name}'
# pattern matching in args
foo = fn {x, y}: x + y
bar = fn [head, ..tail]: head
baz = fn arg, ..rest: argfn match sugar
Mutual recursion
Forward references at module level allow mutual recursion without special syntax:
Application
Prefix application, right-to-left nesting:
log 'hello'
add 1, 2
# nested — right to left
foo bar spam ham
# == foo (bar (spam ham))
# multiline — indented args
add
mul 2, 3
mul 3, 4Use ; as a strong inline separator (stronger than ,):
Partial application with ?
? creates an anonymous function scoped to the current expression or pipe segment:
add5 = add 5, ?
add5 = ? + 5
filter is_divisible ?, 2 # == filter fn $: is_divisible $, 2
map ? * 2 # == map fn $: $ * 2? is transparent through sequences, records, and operators — all ? in the same scope share one parameter:
(...) is an explicit scope boundary:
Pipes
Left-to-right application:
Each pipe segment is its own ? scope:
Pass result as spread arguments:
Error Handling
try unwraps Ok or propagates Err up the call stack:
match handles errors explicitly:
Error chaining:
Modules
Types (work in progress)
# product types
Point = type: u8, u8
Circle = type: {x: u8, y: u8, r: u8}
# sum types / variants
Result = variant T, E:
Ok T
Err E
Shape = variant:
Circle {x: u8, y: u8, r: u8}
Rect {x: u8, y: u8, w: u8, h: u8}
Nil ()
# opaque types
UserId = type: ..u64
# generic types
Option = variant T:
Some T
NoneConstruction and matching: