#Built-Ins
This document defines the currently implemented Masterbelt built-in types, values, functions, and operators.
The built-in set is intentionally minimal at this stage. Future built-in additions must extend this document before or together with implementation changes.
#Built-In Types
The implemented built-in primitive types are:
null: the type of the null literal.bool: the type of boolean literals.string: the type of string literals.
The implemented built-in numeric types are:
| Masterbelt | Signedness | Width |
|---|---|---|
int | signed | native (host language's natural width) |
int8 | signed | 8 bits |
int16 | signed | 16 bits |
int32 | signed | 32 bits |
int64 | signed | 64 bits |
uint | unsigned | native (host language's natural width) |
uint8 | unsigned | 8 bits |
uint16 | unsigned | 16 bits |
uint32 | unsigned | 32 bits |
uint64 | unsigned | 64 bits |
The default type of an integer literal that has no type annotation, pushdown target, or cast prefix is int.
Built-in type names are written in lowercase.
#Numeric Type Classes
The language distinguishes three internal numeric type classes. These classes are not types in their own right: they cannot appear in a type expression position and they do not name a binding. They exist to let the checker describe operations that require a numeric operand or target.
numeric: the union of every built-in numeric type listed above.snumeric: the union of every signed built-in numeric type (int,int8,int16,int32,int64).unumeric: the union of every unsigned built-in numeric type (uint,uint8,uint16,uint32,uint64).
An alias whose target resolves to a numeric type belongs to the same class as the resolved target.
The implemented built-in generic type constructors are:
list<T>: a homogeneous sequence of values of element typeT.map<K, V>: an associative mapping from key typeKto value typeV.
Generic type constructors take their type arguments between < and > separated by ,. Each type argument is itself a type expression.
The number of type arguments must match the constructor:
listtakes exactly one type argument.maptakes exactly two type arguments.
Built-in type names and generic type constructor names are available only in type expression positions. They do not introduce value bindings.
#Built-In Product Types
Error is the built-in product type used to represent a recoverable failure produced by a failable function.
type Error = { message: string }
The Error name is reserved at the type binding space: declaring a type, enum, or master named Error is a type checking error reported through the standard reserved-name diagnostic. The only surface use of Error is as the argument to fail (fail Error { message: "..." }); it does not appear in function return types or in user-visible unions. See syntax.md and semantics.md for the integration with fail.
#Built-In Values
The implemented built-in values are the literal words null, true, and false.
#Built-In Functions and Operators
The implemented built-in free functions are:
fn range(start: int, end: int): list<int>— yields the integersstart, start + 1, ..., end - 1in ascending order. Whenstart >= endthe result is empty. The function is total: every input produces a value oflist<int>without effects.
range is exposed as a value binding in the same module-scope name space as user-declared functions. The name range cannot be redeclared (a user declaration of const range = ... or fn range(...) is rejected through the reserved built-in names rule extended to value-position built-ins).
Although range(start, end) returns a list<int> at the type level, every supported codegen target recognises a for i in range(a, b) { ... } source form and emits a counted loop instead of materializing the list (see codegen/golang.md, codegen/typescript.md, and codegen/csharp.md). The optimization is a target-emission concern; the language semantics treat range as returning a regular list.
#Operator Methods
Every unary or binary operator in syntax.md is defined as a method on the operand (for unary) or the left operand (for binary). The surface form a OP b is equivalent to the method call a.METHOD(b); the unary form OP a is equivalent to a.METHOD().
The complete operator-to-method mapping is:
| Surface | Method | Arity |
|---|---|---|
!a | not | unary |
+a | plus | unary |
-a | minus | unary |
a + b | add | binary |
a - b | sub | binary |
a * b | mul | binary |
a / b | div | binary |
a % b | mod | binary |
a == b | eql | binary |
a != b | neq | binary |
a < b | lt | binary |
a <= b | lteq | binary |
a > b | gt | binary |
a >= b | gteq | binary |
a & b | and | binary |
| `a | b` | or |
a ^ b | xor | binary |
a << b | lshift | binary |
a >> b | rshift | binary |
The method must exist on the operand's type. Type checking of an operator expression follows the same overload resolution rules used for any other method call (see types.md). A user product type may declare any subset of these methods to opt that operator in; declaring a method whose name is not in this table is permitted but has no operator interpretation.
#Built-In Fields on Primitive and Generic Types
A few built-in types expose readonly fields that record a side-effect-free property of the value. The fields are not method calls — they participate in the regular value.field member-access form defined in syntax.md — so the surface form has no parentheses.
string.length: int— the number of Unicode codepoints in the string (rune count, not byte count). The value matches Go'sutf8.RuneCountInString; each codepoint counts as one regardless of its UTF-8 byte size.list<T>.size: int— the number of elements in the list.map<K, V>.size: int— the number of entries in the map.
The fields are not visible as free identifiers and cannot be redefined; they exist on every value of the corresponding type. An alias whose target resolves to one of these types inherits the same fields.
#Built-In Operator Methods on Primitive Types
For every built-in primitive type listed earlier in this document, the language exposes a fixed set of operator methods as if the type carried them in its method list. These methods are not visible as free identifiers and cannot be redefined; they exist only to make operator expressions on primitive operands type-check.
The intrinsic operator methods provided for each primitive type are:
- Every numeric type
N(int,int8, ...,uint64):fn add(other: N): N,fn sub(other: N): N,fn mul(other: N): N,fn div(other: N): N,fn mod(other: N): Nfn eql(other: N): bool,fn neq(other: N): bool,fn lt(other: N): bool,fn lteq(other: N): bool,fn gt(other: N): bool,fn gteq(other: N): boolfn and(other: N): N,fn or(other: N): N,fn xor(other: N): Nfn lshift(other: N): N,fn rshift(other: N): Nfn plus(): N(unary+)fn minus(): N(unary-; provided on signed numeric types only)
bool:fn eql(other: bool): bool,fn neq(other: bool): boolfn and(other: bool): bool,fn or(other: bool): bool,fn xor(other: bool): boolfn not(): bool(unary!)
string:fn eql(other: string): bool,fn neq(other: string): boolfn lt(other: string): bool,fn lteq(other: string): bool,fn gt(other: string): bool,fn gteq(other: string): boolfn add(other: string): string(concatenation)
null:fn eql(other: null): bool,fn neq(other: null): bool
The built-in generic constructors expose operator methods as well:
list<T>:fn add(other: list<T>): list<T>— element-wise concatenation; the result lists the receiver's elements followed by the argument's elements.
map<K, V>:fn add(other: map<K, V>): map<K, V>— last-wins merge; the result contains every entry of the receiver and every entry of the argument, with a key present in both taking the argument's value.
An alias whose target resolves to a primitive type or a built-in generic application inherits the corresponding intrinsic operator method set.
Operator method calls on primitive operands are emitted by every supported target as that target's native operator. Operator method calls on built-in generic operands (list, map) are emitted as a call into the target's runtime helper file; see each target's specification for the surface translation and runtime file emission.