Local standard library
Available in 0.3.0-dev. These built-in namespaces need no imports or external packages. File paths are relative to the process working directory, not the script’s directory.
| API | Behavior |
|---|---|
args() | List of script arguments, excluding executable and script paths |
io.read_text(path) | Read a regular local file, up to 1 MiB; I/O failures are located errors |
json.load(path) | Read a local JSON document and decode it |
json.decode(text) | Decode one JSON value; reject duplicate keys, trailing input, out-of-range integers, nonfinite floats, excessive nesting, and oversized collections |
json.encode(value) | Compact deterministic JSON; IP/CIDR values become strings, records become objects, enums become variant strings |
env.get(name) | Read an environment variable; returns null if absent and a String if present, including an empty string |
path.join(part, ...) | Join one or more strings using host path rules |
path.basename(path) | Host basename |
path.dirname(path) | Host parent directory |
net.ip(text) | Parse an IPv4 or IPv6 String into an IP value |
net.subnet(text) | Parse IPv4 or IPv6 CIDR, normalizing host bits |
net.is_ip(text) | Check IP syntax without raising an error for an invalid address |
net.is_subnet(text) | Check CIDR syntax without raising an error for an invalid CIDR |
net.allocate(parent, prefixes) | Plan variable-size blocks inside a Subnet; output follows request order |
net.contains(subnet, ip_or_subnet) | Address or whole-subnet membership; also subnet.contains(value) |
net.overlaps(a, b) | Whether two Subnets share any addresses |
net.intersection(a, b) | Their common Subnet, or null |
net.subtract(a, b) | Exact CIDR cover of addresses in a but not b |
net.summarize(subnets) | Sorted minimal CIDR cover, removing duplicates and contained blocks |
io.write_text(path, text) | Replace a regular file via a temporary sibling; maximum 1 MiB |
io.mkdir(path) | Create missing directories |
client.request(method, url[, options]) | Bounded outgoing HTTP/HTTPS request; status, headers and body Map |
time.now() / time.unix_ms() | Current UTC RFC3339 String / Unix milliseconds Int |
time.parse(text) / time.format(milliseconds) | RFC3339 to milliseconds / milliseconds to UTC RFC3339 |
time.sleep(milliseconds) | Cancellable delay from 0 through 60,000 ms |
crypto.sha256(text) | SHA-256 hexadecimal digest; not a password-hashing API |
crypto.random_hex(bytes) | 1..256 cryptographically random bytes encoded as hex |
crypto.constant_time_equal(a, b) | String comparison, constant time for equal-length strings |
div(a, b) | Exact integer quotient, truncating toward zero |
All functions validate arity and expected argument types. Use bracket access when JSON keys collide with map methods such as keys, values, has, or length.
JSON numeric and collection behavior
Integral JSON tokens become Int values without float conversion. Tokens containing a decimal point or exponent become finite Float values. The integer range is -9223372036854775808 to 9223372036854775807.
JSON nesting is limited to 128. Individual lists/objects are limited to 65,536 entries. Encoding visits at most 65,536 values and produces at most 1 MiB. It rejects cycles, functions, and agents. Repeated aliases are encoded as ordinary repeated data within those budgets.
Example
let config = json.decode("{\"address\":\"10.20.0.1\"}")
let allowed = 10.20.0.0/16
print(net.ip(config.address) in allowed)
print(json.encode({allowed: allowed, ok: true}))
Expected output:
true
{"allowed":"10.20.0.0/16","ok":true}
Side effects
File APIs can read and write local data; client.request contacts the supplied endpoint. Environment access is explicit. Reports and print() write to the configured output stream. The interpreter does not automatically redact arbitrary user output.
HTTP client
Options are a Map with body (String up to 1 MiB), headers (up to 64 String
entries/32 KiB), and timeout_ms (1..60000, default 10000). Unknown options are
errors. The result is {status: Int, headers: Map, body: String}; response header
names are lowercase. HTTP error statuses are ordinary responses. Transport/TLS,
timeout, and oversized-response failures raise a catchable I/O Error. Body size
is capped at 1 MiB and response headers at 32 KiB. Redirects are returned without
following them. Embedded URL credentials are rejected; pass explicit headers.
The interpreter’s deadline also applies to requests.
The client uses the host HTTP proxy environment and normal TLS verification.
It is distinct from the serve-mode http namespace and does not provide streaming
or connection pooling across calls yet.
Network operations
IPv6 is created through net.ip("2001:db8::1") and
net.subnet("2001:db8::/64"); bare literals remain IPv4. Different address
families never overlap. Individual IPv4-mapped addresses are accepted and treated
as IPv4 for membership; mapped IPv6 CIDRs are rejected in favor of IPv4 notation.
split and allocate support both families, with the existing 65,536-result
bound. Set subtraction works on CIDRs and produces at most 128 blocks for one
IPv6 exclusion. Summarization accepts at most 65,536 Subnets.
File replacement
io.write_text refuses an existing directory or symlink. Its parent directory
must exist. It writes and syncs a temporary sibling before renaming it over the
destination, retaining the existing file permission bits where supported.
Replacement changes file identity and may not retain ACLs or hard-link behavior;
atomicity follows the host rename semantics. These APIs are not a filesystem
sandbox.