Random

Loft provides three functions for randomness:

rand(lo, hi) — a random integer in [lo, hi] inclusive. rand_seed(seed) — seed the random number generator for reproducible results. rand_indices(n) — a vector of n integers [0..n-1] in a random order.

The generator is a fast PCG64 algorithm. Without an explicit seed the generator starts from a fixed default seed, so results are reproducible across runs unless you seed with a time-based value.

fn main() {

Basic random integers

'rand(lo, hi)' returns a uniformly distributed integer in [lo, hi]. Call 'rand_seed' first to choose the sequence.

  rand_seed(42);
  r = rand(1, 6);

simulated die roll: 1..6

  assert(r >= 1 && r <= 6, "die roll out of range: {r}");

The same seed always produces the same sequence.

  rand_seed(0);
  a = rand(0, 999);
  rand_seed(0);
  assert(rand(0, 999) == a, "seeded rand must be reproducible");

'rand' returns null when lo > hi.

  assert(!rand(10, 5), "invalid range returns null");

Random ordering: rand_indices

'rand_indices(n)' returns a vector containing 0, 1, ..., n-1 in a random order. Use the indices to visit another collection in random order without copying it.

  rand_seed(7);
  order = rand_indices(5);
  assert(len(order) == 5, "size must be 5");

Every value 0..4 appears exactly once.

  items =["apple", "banana", "cherry", "date", "elderberry"];
  seen =[for i in 0..5 {
    false
  }];
  for idx in order {
    seen[idx] = true;
  }
  all_seen = true;
  for s in seen {
    if !s {
      all_seen = false
    }
  }
  assert(all_seen, "rand_indices must cover all positions");

Sampling without replacement

Pick k distinct items from a list by taking the first k indices.

  rand_seed(1);
  indices = rand_indices(len(items));

Take the first 3 items in random order.

  picked = "";
  for i in 0..3 {
    if i > 0 {
      picked += ", "
    }
    picked += items[indices[i]]
  }

'picked' now contains 3 distinct fruit names in a random order.

  assert(len(picked) > 0, "should have picked some items: {picked}");
}