Language
Language Reference
Complete reference for all Rey language features — types, syntax, semantics, and the standard library.
v0.2.0Definitive
Contents
TypesVariablesOperatorsControl FlowFunctionsStructsEnumsMatchVec & HashMapResult & OptionImportsBuilt-insStandard LibraryTypes
Rey is statically typed. Every expression has a type known at compile time.
| Type | Size | Example | Notes |
|---|---|---|---|
Int | 64-bit | 42, -7 | Signed integer |
Float | 64-bit | 3.14 | IEEE 754 double |
Bool | 1-bit | true, false | — |
String | heap | "hello" | UTF-8 |
Void | 0 | — | Return only |
Vec<T> | heap | [1, 2, 3] | Resizable array |
HashMap<K,V> | heap | HashMap.new() | Hash table |
Result<T> | heap | — | Ok or Err |
Option<T> | heap | — | Some or None |
Union and nullable types:
var x: Int | String = 42; "color:#637099">// union
var y: Int? = null; "color:#637099">// nullableVariables
var x = 10; "color:#637099">// inferred: Int
var msg = "hi"; "color:#637099">// inferred: String
var flag = true; "color:#637099">// inferred: Bool
"color:#637099">// explicit annotation
var count: Int = 0;
"color:#637099">// reassignment — same type only
x = x + 1; "color:#637099">// ok
"color:#637099">// x = "hello"; // COMPILE ERRORVariables are mutable. Type cannot change after declaration.
Operators
| Category | Operators | Notes |
|---|---|---|
| Arithmetic | + - * / % | Standard math |
| Comparison | == != < > <= >= | Returns Bool |
| Logical | && || ! | Short-circuit |
| String concat | + | "a" + "b" |
| Assignment | = += -= *= /= | In-place |
| Ternary | cond ? a : b | Inline if |
Control Flow
control.rey
"color:#637099">// if / else
if x > 0 {
println("positive");
} else {
println("non-positive");
}
"color:#637099">// while loop
var i = 0;
while i < 10 {
i += 1;
}
"color:#637099">// for-in loop
var nums = [1, 2, 3];
for n in nums {
println(n);
}
"color:#637099">// break / continue
for n in nums {
if n == 2 { continue; }
println(n);
}Functions
functions.rey
func add(a: Int, b: Int): Int {
return a + b;
}
func greet(name: String): Void {
println("Hello, " + name);
}
"color:#637099">// lambdas
var double = (x: Int) => x * 2;
"color:#637099">// higher-order
func apply(f: (Int) => Int, x: Int): Int {
return f(x);
}
println(apply(double, 5)); "color:#637099">// 10All parameters and return types must be annotated. Rey does not support variadic or default parameters.
Structs
structs.rey
struct Point {
pub x: Int,
pub y: Int,
}
struct User {
pub name: String,
pub age: Int,
}
var p = Point { x: 10, y: 20 };
var u = User { name: "Alice", age: 30 };
println(p.x); "color:#637099">// 10
println(u.name); "color:#637099">// Alice
p.x = p.x + 1; "color:#637099">// mutate field
func midpoint(a: Point, b: Point): Point {
return Point { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
}Fields marked pub are accessible outside the module.
Enums
enums.rey
enum Color { Red, Green, Blue }
enum Shape {
Circle(Int), "color:#637099">// radius
Rect(Int, Int), "color:#637099">// w, h
Point,
}
var c = Color.Red;
var s = Shape.Circle(5);
match c {
Color.Red => println("red"),
Color.Green => println("green"),
Color.Blue => println("blue"),
}Match
match is exhaustive — all cases must be covered, or a wildcard _ must be present.
match.rey
match score {
100 => println("perfect"),
90..99 => println("excellent"),
70..89 => println("good"),
_ => println("needs work"),
}
"color:#637099">// match as expression
var label = match status {
Status.Ok => "success",
Status.Err => "failure",
Status.Pending => "waiting",
};
"color:#637099">// struct destructuring
match point {
Point { x: 0, y: 0 } => println("origin"),
Point { x, y } => println(x + ", " + y),
}Vec & HashMap
vec.rey
var nums = [1, 2, 3, 4, 5];
nums.push(6);
nums.pop();
var len = nums.len();
var doubled = nums.map((x) => x * 2);
var evens = nums.filter((x) => x % 2 == 0);
var sum = nums.fold(0, (acc, x) => acc + x);
var joined = nums.join(", ");hashmap.rey
var scores = HashMap.new();
scores.set("Alice", 95);
scores.set("Bob", 87);
var alice = scores.get("Alice"); "color:#637099">// 95
var has = scores.has("Carol"); "color:#637099">// false
var keys = scores.keys(); "color:#637099">// Vec<String>
var vals = scores.values(); "color:#637099">// Vec<Int>Result & Option
result.rey
var r = readFile("data.txt"); "color:#637099">// Result<String>
if r.isOk() {
println(r.unwrap());
} else {
println("Error: " + r.unwrapOr("unknown"));
}
var maybe: Option<Int> = Option.some(42);
if maybe.isSome() {
println(maybe.unwrap()); "color:#637099">// 42
}
"color:#637099">// chaining
var val = scores
.getOption("Alice")
.map((s) => s * 2)
.unwrapOr(0);Imports & Exports
imports.rey
"color:#637099">// import a file
import "./utils.rey";
"color:#637099">// named imports
import { add, subtract } from "./math.rey";
"color:#637099">// module import
import math from "./math.rey";
math.add(1, 2);
"color:#637099">// export
export pub func greet(name: String): String {
return "Hello, " + name;
}
"color:#637099">// private — not exported
func internal(): Void {
println("private");
}The import resolver runs at compile time. Circular imports are a compile error.
Built-in Functions
| Function | Signature | Description |
|---|---|---|
println | (Any): Void | Print with newline |
print | (Any): Void | Print without newline |
readLine | (): String | Read from stdin |
readFile | (String): Result<String> | Read file |
writeFile | (String, String): Result<Void> | Write file |
parseInt | (String): Result<Int> | Parse to Int |
parseFloat | (String): Result<Float> | Parse to Float |
toString | (Any): String | Convert to string |
len | (String): Int | String length |
exit | (Int): Void | Exit process |
Standard Library
String
.split(sep).trim().toUpperCase().toLowerCase().contains(str).startsWith(str).replace(from, to).len()Vec<T>
.push(val).pop().get(i).len().map(fn).filter(fn).fold(init, fn).join(sep)HashMap<K,V>
.set(k,v).get(k).has(k).delete(k).keys().values().len()Result<T>
.isOk().isErr().unwrap().unwrapOr(d).map(fn).getError()