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).
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.
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.
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.
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.
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.
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.
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.
** — exponentiation. Int raised to a non-negative Int stays an Int
(checked, so it overflows catchably); a negative exponent or any Float
operand promotes to Float. 0 ** <negative> is a catchable division by zero.
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. The one-argument Doge form
range(n) is compiled as range(0, n), so the runtime has one signature.
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.
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.
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.
float(x) — Int and Bool widen to 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 truncated toward zero, Bool to 0/1, a Str
parsed as a whole number. A Str that isn’t a number is a catchable
ValueError; other types are a TypeError.
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.