Getting Started
Rex programs are one expression, optionally preceded by top-level declarations:
type— algebraic data types (ADTs)class/instance— type classes and instancesfn— top-level functions
Note: This tutorial focuses on writing Rex code. If you want to embed Rex in Rust, see Embedding.
Running Rex
From this repository, you can run a file:
cargo run -p rex -- run rex/examples/record_update.rex
Or evaluate a small snippet inline:
cargo run -p rex -- run -c 'map ((*) 2) [1, 2, 3]'
What you should see
The CLI prints the evaluated value of the final expression in your program. If something fails, you’ll get a parse/type/eval error (often with a span).
What “one expression” means
Even with declarations, the program result is the final expression:
fn inc : i32 -> i32 = \x -> x + 1
let xs = [1, 2, 3] in
map inc xs
The program above:
- Declares a top-level function
inc. - Creates a list
xs. - Evaluates
map inc xsas the program’s result.
Comments
Comments use {- ... -}:
{- This is a comment -}
1 + 2
Whitespace and layout
Most whitespace is insignificant, but some constructs are easiest to read in “layout style”:
let
x = 1,
y = 2
in
x + y
Commas between let bindings are required. The parser also accepts many one-line forms, but
multi-line layout tends to be easier to debug.
Type-class and instance method blocks are also written by indentation:
class Size a
size : a -> i32
You may also see the optional where keyword in class/instance headers:
class Size a where
size : a -> i32
Both forms are accepted.
Your first “real” Rex file
Create a file hello.rex:
let
greet = \name -> "hello, " + name
in
greet "world"
Run it:
cargo run -p rex -- run hello.rex
Unicode (λ, →) versus ASCII
Rex accepts both:
\and->λand→
Use whichever your editor makes pleasant. The repo’s examples use a mix.