@std/prelude

API Reference

implicit scope
Symbols in @std/prelude are available in every Rasmalai source file out-of-the-box without an explicit import. Explicit imports are supported for disambiguation.

class Any

Untyped escape hatch. Nothing on an `Any` is resolved statically, so cast before use with `v as Int` or `v as String`.

class Array

Dense growable sequence with `Int` indexes. Methods, all compiler builtins needing no import: `length(): Int`, `len(): Int`, `isEmpty(): Bool`, `push(item)`, `pop()`, `map(closure)`, `filter(closure)`. `length` and `len` also read as properties. `map` builds a new array from the closure's return value; `filter` keeps the elements the closure accepts and keeps their original type. `pop()` takes the last element and gives `null` on an empty array. Reading an index past the end throws `index out of bounds`, so check the length first. Search and fold helpers (`find`, `findIndex`, `some`, `every`, `reduce`, `join`, `reversed`) are extension methods below.

fn every(predicate: fn(T): Bool): Bool

Whether every element satisfies `predicate`.

predicate — called once per element, in index order.

returns — false on the first rejection, true for an empty array.

print([4, 9, 16].every((x: Int): Bool => x > 0));
Run in Playground
fn find(predicate: fn(T): Bool): T?

First element satisfying `predicate`.

predicate — called once per element, in index order.

returns — the first match, or `null` when the array is empty or nothing matches.

let xs = [4, 9, 16];
print(xs.find((x: Int): Bool => x > 5) ?? -1);
Run in Playground
fn findIndex(predicate: fn(T): Bool): Int

Where the first matching element sits.

predicate — called once per element, in index order.

returns — the zero-based index of the first match, or -1 when the array is empty or nothing matches.

let xs = [4, 9, 16];
print(xs.findIndex((x: Int): Bool => x > 5));
Run in Playground
fn join(separator: String): String

Render every element and glue the pieces with `separator`.

separator — text between elements; `""` when omitted.

returns — the joined text, `""` for an empty array.

print([4, 9, 16].join(" | "));
Run in Playground
fn reduce(initial: U, reducer: fn(U, T): U): U

Left fold: thread `initial` through `reducer` over each element.

initial — value handed to the first `reducer` call.

reducer — called with the accumulator and the next element.

returns — the last accumulator, which is `initial` for an empty array.

print([4, 9, 16].reduce<Int>(0, (acc: Int, x: Int): Int => acc + x));
Run in Playground
fn reversed(): Array<T>

Reverse this array into a copy.

returns — a new array holding the same elements back to front.

print([4, 9, 16].reversed().join(","));
Run in Playground
fn some(predicate: fn(T): Bool): Bool

Whether any element satisfies `predicate`.

predicate — called once per element, in index order.

returns — true on the first match, false for an empty array.

print([4, 9, 16].some((x: Int): Bool => x == 9));
Run in Playground
class ArrayIter

Index-based iterator over an array. It holds the array and a cursor, walks the array in place, and yields `null` once the cursor passes the end. `for..in` accepts it directly.

init(arr: Array<T>)

fields

  • arr: Array<T>
  • i: Int
fn next(): T?

Take the next element and step the cursor on.

returns — the element at the cursor, or `null` past the end.

class Bool

Foundation boolean type: `true` or `false`. Methods: `toString(): String`, which prints `true` or `false`.

class Char

Single scalar view into a `String`. The checker treats a `Char` as a `String`, and `charCodeAt` is how you read the scalar value.

class Date

Calendar view over the wall clock. Catalog stub: `@std/time` owns the clocks, and none of them report calendar dates.

class Error

Error value. Catalog stub: `throw` raises a `String` message and `catch (e)` binds it, so an `Error` carries nothing on its own.

class FastFloat

Relaxed float type. Produced by `Float.asFast()` and read back with `asStrict()`. It mixes with `Float` only after an explicit conversion, and comparing one with the other needs `82.5.asFast()`-style literals.

class Float

Foundation float type: an IEEE-754 double. Methods: `toString(): String`, `toBits(): Int`, `asFast(): FastFloat`, `asStrict(): Float`. Statics: `Float.nan()`, `Float.isNaN(x)`, `Float.fma(a, b, c)`, `Float.fromBits(bits)`. A `Float` and a `FastFloat` never mix in one expression; the mix is `E305`, so name the conversion you mean.

class GenRef

Generational reference for cyclic edges. `GenRef.of(x)` takes a reference without raising the owner's retain count, and `.get()` gives `null` once the owner is gone, so a back edge never keeps a graph alive. ARC owns, `GenRef` points back; use `#[Allow(CyclicReference)]` on a field for a strong cycle you mean to break yourself.

class Int

Foundation integer type: a signed 64-bit whole number. Methods: `toString(): String`. Convert a float with `Int(x)`, which truncates toward zero, and render a number with `x.toString()`.

class Map

Insertion-ordered key-value table. Catalog stub: `Map` and its methods live in `@std/collections`.

class Promise

One-shot eventual value: `Pending` (0), `Fulfilled` (1), `Rejected` (2). Combinators attach continuations; `wait()` parks the OS thread until settlement. The first settlement wins and later calls are ignored. A rejection carries a `String` reason. Every combinator hands back a new promise and leaves this one as it is, so a chain of them settles independently at each link. Handlers added after settlement run at once on the calling thread.

init(state: Int, value: T, reason: String, syncId: Int)

fields

  • _handlers: Array<fn(T): Void>
  • _reason: String
  • _rejectHandlers: Array<fn(String): Void>
  • _state: Int
  • _syncId: Int
  • _value: T
fn all(promises: Array<Promise<T>>): Promise<Array<T>>

Wait for every promise and fulfill with the payloads in input order, whatever order they settle in. The first rejection wins and rejects the result; later settlements are ignored. An empty array fulfills with `[]`.

promises — promises to wait on.

returns — a promise for the payloads, or the first rejection.

let ps: Array<Promise<Int>> = [Promise.resolve(1), Promise.resolve(2)];
let all: Result<Array<Int>, String> = Promise.all<Int>(ps).wait();
let got: Array<Int> = all.unwrap();
print(got.join(","));
Run in Playground
fn allRej(out: Promise<Array<U>>): fn(String): Void

Build the rejection continuation `Promise.all` hands each input. Internal: one of these rejects `out` and settles the combinator.

out — promise the first rejection rejects.

returns — a continuation taking the reason.

fn allSettled(promises: Array<Promise<T>>): Promise<Array<PromiseResult<T>>>

Wait for every promise and never reject. Each input turns into a `PromiseResult` in input order holding either the payload or the rejection message. An empty array fulfills with `[]`.

promises — promises to wait on.

returns — a promise for one settlement record per input.

let ps: Array<Promise<Int>> = [Promise.resolve(5), Promise.reject<Int>("bad")];
let all: Result<Array<PromiseResult<Int>>, String> = Promise.allSettled<Int>(ps).wait();
let got: Array<PromiseResult<Int>> = all.unwrap();
print(got[0].status);
print(got[1].reason);
Run in Playground
fn allSlot(slots: Array<U>, out: Promise<Array<U>>, counterId: Int, n: Int, idx: Int): fn(U): Void

Build the fulfillment continuation `Promise.all` hands each input. Internal: one of these writes its slot, and the last one to finish fulfills `out` with the slots in input order.

slots — scratch array holding one payload per input.

out — promise the last input fulfills.

counterId — registry id of the remaining-count atomic.

n — how many inputs there are.

idx — this input's index.

returns — a continuation taking the payload.

fn any(promises: Array<Promise<T>>): Promise<T>

Fulfill with the first payload to arrive. Only once every input has rejected does the result reject, and then with `"AggregateError: all promises rejected"`. An empty array rejects at once with `"AggregateError: no promises"`.

promises — promises to try.

returns — a promise for the first payload, or the aggregate rejection.

let mixed: Array<Promise<Int>> = [Promise.reject<Int>("no"), Promise.resolve(5)];
print(Promise.any<Int>(mixed).wait().unwrap());
Run in Playground
fn anyFwd(out: Promise<U>): fn(U): Void

Build the fulfillment continuation `Promise.any` hands each input. Internal: one of these fulfills `out`, and only the first to arrive has any effect.

out — promise the winner fulfills.

returns — a continuation taking the payload.

fn anyRej(out: Promise<U>, counterId: Int): fn(String): Void

Build the rejection continuation `Promise.any` hands each input. Internal: one of these decrements the count, and the one that finds nothing left rejects `out` with the aggregate message.

out — promise the aggregate rejection settles.

counterId — registry id of the remaining-count atomic.

returns — a continuation taking the reason.

fn attach(onF: fn(T): Void, onR: fn(String): Void): Void

Register both continuations. A pending promise queues one pair per call; a settled promise runs the matching continuation at once on the calling thread and queues nothing. Only one of the two ever runs for a given promise.

onF — called with the payload on fulfillment.

onR — called with the message on rejection.

let wr = Promise.withResolvers<Int>();
wr.promise.attach((v: Int): Void => print("got", v), (e: String): Void => print("bad", e));
wr.resolve(7);
Run in Playground
fn catchReject(onRejected: fn(String): U): Promise<U>

Chain a rejection handler. A fulfillment passes through with its payload untouched; a rejection runs the closure and the new promise fulfills with the closure's result, so the chain recovers instead of staying rejected.

onRejected — runs with the reason and produces the new payload.

returns — a promise that turns this rejection into a fulfillment.

let r: Result<Int, String> = Promise.reject<Int>("x").catchReject<Int>((e: String): Int => 99).wait();
print(r.unwrap());
Run in Playground
fn finallyDo(onFinally: fn(): Void): Promise<T>

Chain a handler that runs on either outcome and leaves it alone. The closure runs before the new promise settles, so what it prints lands before the value read from `wait()`.

onFinally — runs once the promise settles, either way.

returns — a promise carrying the original outcome.

let r: Result<Int, String> = Promise.resolve(7).finallyDo(() => print("done")).wait();
print(r.unwrap());
Run in Playground
fn freshId(): Int

Take the next id from the shared counter. Internal: every promise needs its own mutex and condvar id.

returns — a fresh registry id.

fn fulfill(val: T): Void

Settle as fulfilled with `val`. Ignored unless the promise is still pending, so the first settlement wins. Queued handlers run after the guard is released, never while holding it.

val — payload for the fulfillment.

fn race(promises: Array<Promise<T>>): Promise<T>

Settle with whichever input settles first, fulfillment or rejection alike; the first settlement copies across and later ones are ignored. The losing inputs keep running, so avoid handing `race` work that must not continue. An empty array never settles, and `wait()` on the result gives back `Err` after its 5s timeout.

promises — promises to race.

returns — a promise carrying the first settlement.

let ps: Array<Promise<Int>> = [Promise.resolve(1), Promise.resolve(2)];
print(Promise.race<Int>(ps).wait().unwrap());
Run in Playground
fn raceFwd(out: Promise<U>): fn(U): Void

Build the fulfillment continuation `Promise.race` hands each input. Internal: one of these fulfills `out`, and only the first to arrive has any effect.

out — promise the winner fulfills.

returns — a continuation taking the payload.

fn raceRej(out: Promise<U>): fn(String): Void

Build the rejection continuation `Promise.race` hands each input. Internal: one of these rejects `out`, and only the first to arrive has any effect.

out — promise the first rejection rejects.

returns — a continuation taking the reason.

fn reject(reason: String): Promise<T>

A promise that is already rejected.

reason — message the rejection carries.

returns — a rejected promise; `wait()` gives back `Result.Err` holding the same message.

fn rejectWith(reason: String): Void

Settle as rejected with `reason`. Ignored unless the promise is still pending, so the first settlement wins. Queued handlers run after the guard is released, never while holding it.

reason — message for the rejection.

fn resolve(val: T): Promise<T>

A promise that is already fulfilled.

val — payload carried by the promise.

returns — a fulfilled promise; handlers attached later run at once.

fn settledRej(slots: Array<PromiseResult<U>>, out: Promise<Array<PromiseResult<U>>>, counterId: Int, n: Int, idx: Int): fn(String): Void

Build the rejection continuation `Promise.allSettled` hands each input. Internal: one of these writes a `"rejected"` record and decrements the count, and the last one fulfills `out` with every record in input order.

slots — scratch array holding one record per input.

out — promise the last input fulfills.

counterId — registry id of the remaining-count atomic.

n — how many inputs there are.

idx — this input's index.

returns — a continuation taking the reason.

fn settledSlot(slots: Array<PromiseResult<U>>, out: Promise<Array<PromiseResult<U>>>, counterId: Int, n: Int, idx: Int, ok: Bool): fn(U): Void

Build the fulfillment continuation `Promise.allSettled` hands each input. Internal: one of these writes a `"fulfilled"` record and decrements the count, and the last one fulfills `out` with every record in input order.

slots — scratch array holding one record per input.

out — promise the last input fulfills.

counterId — registry id of the remaining-count atomic.

n — how many inputs there are.

idx — this input's index.

ok — true for the fulfillment continuation.

returns — a continuation taking the payload.

fn then(onFulfilled: fn(T): U): Promise<U>

Chain a fulfillment handler. A rejection skips the closure and reaches the new promise unchanged, so `catchReject` is what recovers from one. The closure's return value becomes the payload the new promise settles with.

onFulfilled — runs with the payload and produces the new payload.

returns — a promise for the closure's result.

let a: Result<Int, String> = Promise.resolve(20).then<Int>((v: Int): Int => v + 1).wait();
print(a.unwrap());
let b: Result<Int, String> = Promise.reject<Int>("bad").then<Int>((v: Int): Int => v + 1).wait();
print(b.isErr());
Run in Playground
fn wait(): Result<T, String>

Park the calling OS thread until the promise settles, without spinning: it sleeps on a condvar in 1s slices and gives up after 5s. Fine in a plain function or a `Thread.spawn` body; inside an `async fn` it is a compile error, because parking an event-loop task deadlocks.

returns — `Ok(val)` on fulfillment and `Err(reason)` on rejection, and `Err` with a timeout message when nothing settles in 5s.

let r: Result<Int, String> = Promise.resolve(41).wait();
print(r.unwrap());
Run in Playground
fn waitAny(p: Promise<Any>): Result<Any, String>

Park until `p` settles. This is the bridge `await` lowers to, so user code should reach for `await` or `wait()` instead.

p — promise to wait on.

returns — `Ok(val)` on fulfillment, `Err(reason)` on rejection.

fn withResolvers(): PromiseWithResolvers<T>

A pending promise together with the handles that settle it. Use it when the value arrives from somewhere the promise cannot own, such as a worker thread or an OS callback.

returns — a pending promise wrapped with `resolve` and `reject`.

let wr = Promise.withResolvers<Int>();
wr.resolve(42);
let r: Result<Int, String> = wr.promise.wait();
print(r.unwrap());
Run in Playground
class PromiseResult

Settlement record for `Promise.allSettled`. One per input promise, in input order: `status` is `"fulfilled"` or `"rejected"`, `value` holds the payload of a fulfillment, and `reason` the message of a rejection.

init(status: String, value: T, reason: String)

fields

  • reason: String
  • status: String
  • value: T
class PromiseWithResolvers

Manual settlement handles from `Promise.withResolvers`. It holds the pending promise plus the two calls that settle it, which is how a worker thread, an OS callback, or an I/O handler hands a value back into the promise chain.

init(promise: Promise<T>)

fields

  • promise: Promise<T>
fn reject(reason: String): Void

Reject the promise with `reason`. Ignored once the promise has settled; the first settlement wins.

reason — message carried by the rejection.

fn resolve(val: T): Void

Fulfill the promise with `val`. Ignored once the promise has settled; the first settlement wins.

val — payload for the fulfillment.

class RnxHost

Host metadata: `rnx` is ambient in every module with no import. `version` is the compiler version string, `args` holds the CLI arguments after the script path, `cwd()` reads the working directory, and `exit(code)` terminates immediately.

init()

fields

  • args: Array<String>
  • version: String
fn cwd(): String

Read the working directory of the process.

returns — the path the process was started in.

fn exit(code: Int)

Stop the process now. Nothing after the call runs and the exit status is the code given.

code — exit status handed to the host.

class Set

Distinct-member collection. Catalog stub: `Set` and its methods live in `@std/collections`.

class String

Canonical UTF-8 string type. Every index counts characters, not bytes, so a multi-byte character is one step like any other. Methods, all compiler builtins needing no import: `length(): Int`, `len(): Int`, `slice(start: Int, end: Int): String`, `indexOf(needle: String): Int`, `indexOf(needle: String, from: Int): Int`, `trim(): String`, `concat(other: String): String`, `charCodeAt(index: Int): Int`. `length` and `len` also read as properties. `slice` clamps both bounds to the length and gives `""` once the start reaches the end. Both `indexOf` forms give the index of the first match at or after their start, or -1 when there is none; an empty needle answers with the start it was given. `trim` strips leading and trailing whitespace. `charCodeAt` gives the Unicode code point of the character at that index, or -1 past the end. Search and transform helpers (`contains`, `startsWith`, `endsWith`, `split`, `replace`, `replaceAll`, `repeat`, `toUpperCase`, `toLowerCase`) are extension methods below.

fn contains(search: String): Bool

Whether `search` occurs anywhere in this string.

search — text to look for; `""` is always contained.

returns — true on a hit, false otherwise.

print("rasmalai/compiler".contains("compiler"));
Run in Playground
fn endsWith(suffix: String): Bool

Whether this string ends with `suffix`.

suffix — text to compare; `""` always matches.

returns — true on a match, false otherwise.

print("rasmalai".endsWith("ai"));
Run in Playground
fn repeat(count: Int): String

Copy this string back to back.

count — how many copies; `0` or less gives `""`.

returns — the repeated text.

print("ab".repeat(3));
Run in Playground
fn replace(target: String, replacement: String): String

Swap the first occurrence of `target` for `replacement`.

target — text to look for.

replacement — text to put in its place.

returns — a new string, or this one unchanged when `target` is absent.

print("rasmalai/compiler".replace("/", "-"));
Run in Playground
fn replaceAll(target: String, replacement: String): String

Swap every occurrence of `target` for `replacement`.

target — text to look for; `""` leaves the string unchanged.

replacement — text to put in place of each hit.

returns — a new string with every occurrence replaced.

print("a-b-c".replaceAll("-", "+"));
Run in Playground
fn split(delimiter: String): Array<String>

Cut this string around every `delimiter`.

delimiter — text to cut on; `""` gives one element per character.

returns — the pieces in order, one element when there is no delimiter.

print("rasmalai/compiler".split("/").length());
Run in Playground
fn startsWith(prefix: String): Bool

Whether this string begins with `prefix`.

prefix — text to compare; `""` always matches.

returns — true on a match, false otherwise.

print("rasmalai".startsWith("ras"));
Run in Playground
fn toLowerCase(): String

Fold this string to lower case. Only ASCII `A` to `Z` change; every other character, accented Latin included, passes through untouched, so `"HÉLLO"` gives `"hÉllo"`.

returns — a new string with the ASCII letters lower-cased.

print("HeLLo".toLowerCase());
Run in Playground
fn toUpperCase(): String

Fold this string to upper case. Only ASCII `a` to `z` change; every other character, accented Latin included, passes through untouched, so `"héllo"` gives `"HéLLO"`.

returns — a new string with the ASCII letters upper-cased.

print("hello".toUpperCase());
Run in Playground
class Void

Absence of a return value. `Void` marks a function that only has effects; `null` is the absent value itself, of type `Null`.

enum Result
  • Err(E)
  • Ok(T)