A method captured together with the receiver it was read off. Two bound
methods are equal only when they name the same method on the very same
instance (a.speak == a.speak, but not b.speak).
The clonable half of a bowl: a sender plus a shared receiver over the same
channel. Cloning a handle is how both sides of a pup boundary reach one
channel — a bowl is deliberately shared, not copied. The channel carries
Packed values, since every message crosses a thread boundary.
A first-class function value: which compiled function it is (fn_id, matched
by the generated call_function dispatcher), the name it prints and errors
under, and the cells it captured from its enclosing scope. Two function values
are equal only when they share both the definition and the captured cells.
A DogeError flattened for the trip back from a pup to its fetcher: no Rc,
so it is Send. Rebuilt into a real error (with its original raise site
preserved, so oh no sees the same file/line) by PackedError::into_error.
Build the error a failing amaze <cond> raises. With a message
(amaze cond, msg) the message value’s display form becomes the error text,
mirroring bonk; without one it takes the default doge-flavored line.
Read obj.name as a value, binding a method when there is no field of that
name — the semantics of such f = a.speak. A field always wins over a method
(fields appear on assignment). For a many instance, class_has_method tells
whether the receiver’s class (or an ancestor) defines name; for a List/Dict,
has_builtin_method decides. A name that is neither a field nor a method is
the same catchable error a bare attr_get would raise.
Build the error a bonk <expr> raises. Re-raising a caught Error value
(bonk err) preserves its type, message, and original location; any other
value raises a Bonk whose message is the value’s display form, so bonk 5
reads 5 and bonk "much fail" reads much fail — the text bark prints.
Dispatch a method call on a List or Dict. recv is the receiver, name the
method, args the already-evaluated arguments. A non-collection receiver, an
unknown method, or a wrong argument count is a catchable error.
Resolve a callee to the function it names. A class value calls the same way —
its fn_id is a constructor arm — so both unwrap to their shared
FunctionData. Calling anything else is a catchable TypeError, worded
from the caller’s point of view.
chase.run(cmd, args, stdin) — run cmd with the Str args, feeding it the
Str stdin (or nothing when stdin is none), and give back a Dict
{"code": Int, "stdout": Str, "stderr": Str}. Failing to launch the program,
or output that is not valid text, is a catchable IOError.
dson.emit(value) — a DSON document for value. Dict/List/Str/Int/Float/Bool/
none serialize; any other type, or a non-finite Float, is a catchable error.
The value bound by oh no err!: a structured Error carrying the caught
error’s type, message, and location. A re-raised error keeps its embedded
location; a fresh one takes the catch site’s file/line.
fetch.ext(path) — the extension of the final component including the leading
dot ("c.txt" → ".txt"), or "" when there is none. A leading dot on the
component itself (".gitignore") is not an extension.
fetch.join(a, b) — join two path segments with /, Doge’s one canonical
separator on every platform. If b is absolute (starts with /) it replaces
a entirely; an empty a yields b unchanged.
fetch.list(path) — the names of the entries in directory path, sorted so the
order is stable across runs. A missing path or one that is not a directory is a
catchable IOError.
fetch.make_dir(path) — create the directory at path, along with any missing
parent directories. Doing this when the directory already exists is not an
error. Returns none.
fetch.rename(from, to) — move or rename the file or directory from to to,
replacing to if it already exists. A missing from is a catchable IOError.
Returns none.
fetch.stat(path) — metadata about path as a Dict with size (Int bytes),
modified (Float unix seconds, negative for a pre-epoch time), and is_dir
(Bool). A missing path, or a platform that cannot report the modified time, is a
catchable IOError.
Pack a call’s outcome for the trip back from a pup to its fetcher: the return
value is transferred (the pup is finishing, so a socket in the result moves
home), and a raised error is flattened. A return value that cannot be packed
becomes the fetched error.
The error an indirect call raises when the argument count is wrong, worded
like the compiler’s user-function arity message. max is None when the
function is variadic.
gib() / gib("prompt") — read one line from standard input. An optional
prompt, which must be a Str, is written without a trailing newline and flushed
first. The returned Str has its trailing newline stripped; at end of input the
result is none. A stdin read failure is a catchable IOError.
Whether a List or Dict has a built-in method named name — the gate a bound
method read (such f = xs.append) checks before capturing the receiver. The
method-name sets live beside each collection’s dispatch (list::LIST_METHODS,
dict::DICT_METHODS), so binding and dispatch never disagree.
howl.accept(listener) — block until a client connects, then return the new
connection. A non-listener socket is a catchable TypeError; a closed one is an
IOError.
howl.close(sock) — close a listener or connection now. Idempotent: closing an
already-closed socket is fine. Returns none. Any later operation on it is a
catchable IOError.
howl.get(url) — HTTP(S) GET. Returns a Dict {"status": Int, "body": Str}.
A non-2xx response is returned like any other (its status and body); only a
transport, TLS, or timeout failure is a catchable IOError.
howl.listen(host, port) — bind a TCP listener on host:port (port 0 lets
the OS choose a free one, readable back with howl.port). A bind failure is a
catchable IOError.
howl.recv(conn, max_bytes) — read up to max_bytes bytes from a connection
and return them as text, or none at end of input. Never splits a multi-byte
character: an incomplete trailing sequence is held for the next read, and a
call always yields at least one whole character (or none). max_bytes must
be a positive Int. Genuinely invalid bytes are a catchable IOError.
howl.recv_bytes(conn, max_bytes) — read up to max_bytes raw bytes from a
connection and return them as Bytes, or none at end of input. The binary
counterpart of howl_recv: no UTF-8 reassembly, so bytes are returned exactly
as they arrive and non-text data is never an error — the way to read a binary or
byte-framed body. max_bytes must be a positive Int. Bytes buffered by an
earlier recv/recv_line are returned first so a mixed-use socket loses
nothing. A broken connection is a catchable IOError.
howl.recv_line(conn) — read one line from a connection, without the trailing
newline (a \r\n is trimmed too), or none at end of input. Invalid bytes
are a catchable IOError.
howl.request(method, url, opts) — the general HTTP(S) client. method is one
of [HTTP_METHODS] (case-insensitive). opts is a Dict (or none for no
options) with optional keys "headers" (a Dict of Str→Str) and "body" (a Str,
sent UTF-8, or Bytes, sent raw); any other key is a ValueError. Same return
shape and transport-error rule as howl_get, with response headers included.
howl.send_bytes(conn, bytes) — write raw bytes to a connection, unchanged.
Returns none. The binary counterpart of howl_send: use it to send
arbitrary data (image, PDF, a framed HTTP body) that is not text. A broken pipe
or a non-connection socket is a catchable error.
hunt.groups(pat, text) — the capture groups of the first match, group 0 (the
whole match) first; a group that did not participate is none. none overall
when pat does not match.
needle in container. Python-style: a List tests element membership, a Dict
tests key membership, a Str tests substring. Every other container type is a
catchable type error. Matched by container variant (not a wildcard) so a new
Value variant forces its own decision here.
The sequence a for loop walks: a List’s elements, a Str’s characters, or a
Dict’s keys in insertion order, captured as an owned snapshot taken when the
loop starts. Mutating the original value inside the loop body does not change
what the loop visits. Any other value is a catchable type error.
json.emit(value) — a compact JSON document (no insignificant whitespace) for
value. Dict/List/Str/Int/Float/Bool/none serialize; any other type, or a
non-finite Float (JSON has no NaN/infinity), is a catchable error.
The error a method call raises when the argument count is wrong, worded like
the compiler’s user-function arity message. max is None when the method is
variadic.
nap.mono() — seconds from a fixed process origin, for measuring elapsed time.
Only differences between two readings are meaningful; the origin itself is
arbitrary. Monotonic, so it never jumps when the wall clock is adjusted.
nap.now() — seconds since the Unix epoch (UTC), with sub-second precision.
Never fails: a system clock set before the epoch reads back as a negative
number rather than an error.
nap.parse(text) — unix seconds (as a Float) for an ISO-8601 UTC timestamp
"YYYY-MM-DDTHH:MM:SSZ". The trailing Z is optional. Anything that is not a
well-formed, in-range UTC timestamp is a catchable ValueError with a hint.
nap.rest(seconds) — block for seconds (Int or Float). A negative,
non-finite, or absurdly large duration is a catchable ValueError rather than
the panic Duration::from_secs_f64 would raise on such an input.
nap.stamp(secs) — the ISO-8601 UTC string "YYYY-MM-DDTHH:MM:SSZ" for a unix
timestamp (Int or Float seconds, truncated to a whole second toward negative
infinity). A timestamp outside the representable Int range is a catchable
ValueError.
nerd.abs(x) — magnitude, keeping the argument’s own type. An Int stays an
Int (and never overflows — it is arbitrary precision), a Float a Float, a
Decimal a Decimal.
nerd.min(a, b) — the smaller of two numbers, keeping the winner’s own type;
a tie returns a. Compares exactly across Int/Decimal, via f64 once a Float
is involved.
nerd.pow(base, exponent) — the same rule as the ** operator: Int^Int (a
non-negative exponent) stays an arbitrary-precision Int, Decimal^Int an exact
Decimal, and any other numeric mix returns a Float.
The error a method-call site raises when the receiver’s class has no such
method. recv is an object at every real call site; the non-object branch is
a defensive fallback that mirrors object_class_id.
The class id of a method-call receiver, so the dispatcher can pick the right
arm. Calling a method on a value that has no methods is a catchable
AttrError.
pack.drop(bowl, value) — send value into a bowl (transferring it, so a
socket moves along). Returns none. A non-bowl handle is a catchable type
error; a bowl whose every reader is gone is a catchable IOError rather than a
silent loss.
pack.fetch(pup) — wait for a pup to finish and return its function’s result,
or re-raise (catchably) the error the pup hit, with the pup’s own file/line
preserved. Fetching a pup twice, or a value that is not a pup, is a catchable
error.
Snapshot a value for an ambient position (the globals a pup inherits), never
failing: a value that cannot be packed — a Pup, or one nested too deep —
simply arrives as none in the pup rather than blocking the spawn, since the
pup likely never touches that binding.
pack.sniff(bowl) — block until a value arrives in the bowl, then return it.
A bowl that is empty and can never receive another value again (every writer is
gone) is a catchable IOError rather than a forever-block. A non-bowl handle is a
catchable type error.
Deep-copy a value into its Send boundary form. A Pup cannot cross (a
catchable type error), and a structure nested past [PACK_DEPTH_LIMIT] — which
a self-referential value hits — is a catchable value error rather than an
unbounded copy. mode decides only how a socket is treated.
pack.zoom(f, args) — spawn f onto a new pup, called with the List args.
The callee’s captures and the caller’s top-level variables are snapshotted in;
each argument is transferred in. f must be callable and args must be a List,
or it is a catchable type error. entry is the generated trampoline that
rebuilds a world inside the pup and runs the call.
** — exponentiation. Int raised to a non-negative Int stays an Int
(arbitrary precision); a Decimal raised to a non-negative Int stays an exact
Decimal; a negative exponent or any Float operand promotes to Float. 0 ** <negative> is a catchable division by zero, and an exponent too large to
materialize is a catchable overflow.
range(start, end) — the Ints start, start+1, …, end-1 as an eager List.
When end <= start the List is naturally empty. Both arguments must be Int;
anything else is a catchable type error. A bound too large to be a machine
index is a catchable value error (the List could never fit in memory anyway).
The one-argument Doge form range(n) is compiled as range(0, n), so the
runtime has one signature.
roll.sample(list, k) — a new List of k distinct elements drawn from the
List (by position, so duplicate values may appear if the List holds them). A
k below zero or above the List’s length is a catchable ValueError.
roll.shuffle(list) — a new List holding the same elements in random order.
The argument is left untouched (module functions are pure; only list methods
mutate in place).
Record the script’s command-line arguments. Called once at program startup
(compiled main or the interpreter’s file runner); any later call is ignored,
so the arguments a script sees are fixed for its whole run.
>> — arithmetic (sign-preserving) right shift. A count larger than the value
has bits saturates to the sign fill: 0 for a non-negative value, -1 for a
negative one.
container[start:end:step]. A List yields a new List and a Str a new Str
(character-based); every other value is a catchable type error. Bounds clamp
rather than erroring, matching Python.
Spawn a job onto a fresh pup thread and hand back the pup value. The job
produces the packed result (or error) the pup’s fetch will return. Shared by
both engines: the compiler passes a generated trampoline, the interpreter a
closure that runs a fresh interpreter. A thread the OS refuses to start is a
catchable IOError.
strings.split(s, sep) — a List of the pieces of s between each sep.
Empty pieces are kept ("a,,b" splits into three); splitting on an empty
separator is a catchable ValueError.
bytes(x) — raw bytes from a value. A Str is UTF-8 encoded; a List of Ints
becomes those bytes, each of which must be in 0..=255 (a catchable
ValueError otherwise); a Bytes is returned unchanged. Any other type is a
catchable TypeError.
dec(x) — an exact Decimal. An Int converts exactly; a Bool to 0/1; a
numeric Str parses exactly (dec("0.10")); a Float converts via its shortest
decimal form, so dec(0.1) is exactly 0.1 and not the binary noise a raw
cast would carry. A Decimal is returned unchanged. A non-numeric Str is a
catchable ValueError; other types are a TypeError.
float(x) — Int and Bool widen to Float, Decimal rounds to the nearest Float,
Float is unchanged, a numeric Str is parsed. A non-numeric Str is a catchable
ValueError; other types are a TypeError.
int(x) — Int unchanged, Float and Decimal truncated toward zero, Bool to
0/1, a Str parsed as a whole number (of any size). A Str that isn’t a number
is a catchable ValueError; other types are a TypeError.
Unpack a globals snapshot into the values a pup’s fresh Env fields take, in
the order they were packed. Anything that is not a list snapshot yields no
values, so the fields fall back to none.
Rebuild a fresh Value from its boundary form on the receiving thread, with
brand-new Rcs and cells — no sharing survives the trip, which is exactly the
copy semantics a pup boundary promises.
Unpack v into the values a multiple-assignment binds: the same sequence a
for loop walks (a List’s elements, a Str’s characters, or a Dict’s keys),
split to fixed leading targets plus, when rest is set, a trailing
collector that gathers every surplus value into a List. The returned Vec has
exactly fixed elements without a collector, or fixed + 1 with one (its
last element being the collector List). A non-iterable value or a length that
cannot fill the targets is a catchable error, so pls/oh no can handle it.
A shared, mutable binding cell. Closures capture enclosing variables by
sharing these: a such/param captured by a nested function becomes a Cell,
so a reassignment on either side is visible to the other.
The signature of the generated trampoline a pup runs: build a fresh world from
the globals snapshot, unpack the callee and its arguments, run the call, and
pack the result (or the error) for the trip home. A plain fn pointer, so it
is Send and can be handed to a spawned thread.