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)