Chapter 24 — One-Page Cheat Sheet
Everything that runs today, compressed. (Keep the earlier chapters for the why; this is the what.)
// --- bindings ---
let x = 5 // immutable
var y = 0 // mutable; y = y + 1
let TOP = 800 // top-level let = compile-time constant (literal only)
// --- functions ---
fn add(a: int, b: int) -> int { return a + b }
fn greet(name: string) { println(name) } // no '-> T' = unit (returns nothing)
// --- numbers --- int=i64, float=f64; also i8..i64, u8..u64, f32/f64
let a: u8 = 200 // or 200u8
let f = to_float(a) // int -> float; to_int(f) truncates
let g = u8(300) // range-checked conversion; out of range -> runtime trap
// no implicit coercion; integer overflow traps; % needs integers
a & b a | b a ^ b ~a a << 1 a >> 1 // bitwise/shift: integer-only, width-aware
wrapping_add(a, b) wrapping_sub(a, b) wrapping_mul(a, b) // modular 2^width; trapping stays default
// --- strings (UTF-8) ---
let s = "hi " + name // + concatenates; == compares by content
"value is {x}" // interpolation; \{ \} for literal braces
"{p}" // a struct/enum too, when its type has fn show(self) -> string (Show)
s.len() // byte length s.char_count() // code-point count
s.chars() // [string] one per code point s.bytes() // [u8]
s.split(",") s.parse_int() // -> Option<int>
// Unicode-correct ops: cp_count(s) cp_at(s,i) cp_slice(s,a,b) cp_prefix(s,n)
// cp_insert(s,i,ins) cp_delete(s,i)
// --- bool / control flow --- (conditions MUST be bool; no truthiness)
if x < 0 { } else if x == 0 { } else { }
loop { if done { break } continue }
// --- arrays ---
var xs: [int] = []
xs.append(1) xs.remove_last() xs.remove_at(i) xs.len() xs[0] = 9 // indexing is bounds-checked
for v in xs { } // each element
for i in 0..n { } // exclusive range
for (i, v) in xs { } // index + element
let win = xs[1..4] // borrowed Slice<int> view, no copy; xs.slice(1,4) returns an owned [int]
let dup = xs.clone() // explicit deep copy — arrays, structs, Map, Set
// --- structs, methods, interfaces ---
struct Point { x: int y: int
fn shifted(self, d: int) -> Point { return Point { x: self.x + d, y: self.y } }
}
let p = Point { x: 1, y: 2 } // set every field exactly once
interface Ord { fn compare(self, other: Self) -> int } // 'other: Self' -> bound only
struct V implements Ord { n: int fn compare(self, o: V) -> int { return self.n - o.n } }
interface Shape { fn area(self) -> float } // object-safe (Self only as receiver)
let shapes: [Shape] = [Circle { ... }, Rect { ... }] // interface AS A VALUE TYPE
for s in shapes { println("{s.area()}") } // dynamic dispatch through a vtable
// --- newtypes / refinements --- (distinct nominal types; erase to the base, zero cost)
type UserId = int // UserId(7) constructs; not interchangeable with int or other newtypes
type Email = string // inherits base ==, order, hash, render; Map key + "{id}" ok
type Percent = int where 0 <= self && self <= 100 // predicate checked at construction; Percent(150) -> refinement_violation
// arithmetic needs an explicit unwrap: int(x), compute, re-wrap; refinement checks elided in --release
// --- enums + match --- (exhaustive, no fallthrough)
enum Shape { Circle(r: int) Rect(w: int, h: int) Origin }
let c = Circle(3) // construct positionally...
let d = Circle(r: 3) // ...or by field name, like a struct literal
match s {
case Circle(r) { }
case Rect(w, h) { }
case _ { } // catch-all, must be last
}
// --- errors / optionals --- (no exceptions, no null; from the prelude)
fn f(n: int) -> Result<int, string> { if n < 0 { return Err("neg") } return Ok(n) }
let v = f(3)? // unwrap Ok/Some, or return the Err/None early
// --- generics ---
struct Box<T> { value: T fn get(self) -> T { return self.value } }
fn identity<T>(move x: T) -> T { return x } // returns its arg -> move
fn id<T: Copy>(x: T) -> T { return x } // Copy = everything except struct/array
fn max<T: Ord>(move a: T, move b: T) -> T { if a.compare(b) >= 0 { return a } return b }
struct Map<K: Hash + Eq, V> { /* ... */ } // bounds on generic structs; several with +
// --- functions as values / closures ---
fn apply(f: fn(int) -> int, x: int) -> int { return f(x) }
apply(|n| n + 1, 5) // inline lambda: context gives its types
let h: fn(int) -> int = |n| n * 2 // bound lambda NEEDS the annotation
// --- ownership --- (borrow by default; mut borrows mutably; move transfers)
fn read(p: Point) -> int { return p.x } // borrow
fn bump(mut p: Point) { p.x = p.x + 1 } // mutable borrow
fn take(move p: Point) -> Point { return p } // owns it; may return it
// --- concurrency ---
let ch: Channel<int> = channel(2)
nursery {
spawn worker(ch) // tasks can't outlive the block
}
// send(ch, v) recv(ch)/try_recv(ch) -> Option<T> close(ch) // send on a closed channel traps
// --- talking to C (FFI) --- (extern block = the trust boundary; no separate 'unsafe')
extern "c" {
fn strlen(s: string) -> i64 // string -> const char*
fn fread(mut buf: [u8], n: i64, f: Ptr) -> i64 // [u8]/mut [u8] = buffer; Ptr = opaque handle
}
// --- modules / stdlib ---
import "std/string" as str // str.trim, to_upper, contains, replace, join, ...
import "std/list" as list // list.map, filter, reduce, sort
import "std/map" as mp // mp.Map<K, V> (any Hash+Eq key, incl. structs): set, get -> Option<V>, has, size, keys -> [K]
// names beginning with _ are private to their module
// --- contracts + verification ---
fn clamp(x: int, lo: int, hi: int) -> int
requires lo <= hi
ensures result >= lo
ensures result <= hi
{ if x < lo { return lo } if x > hi { return hi } return x }
assert(cond, "message") // inline check; elided in --release
// inglec --emit=run | check | prove | replay | trace(--tape) | docs | c [--release]
// inglec -o <bin> file.ig // compile to a standalone native binary (Chapter 22)