Built-ins, no imports required
Every built-in type, function and capability available in any Capa program. For language syntax and semantics, see the language reference.
Primitive types
| Type | Size / Range | Notes |
|---|---|---|
| Int | 64-bit signed | Arithmetic does not check for overflow |
| Float | 64-bit IEEE 754 | |
| String | UTF-8 | Immutable |
| Bool / Char | true/false · code point | Char is a str of length 1 at runtime |
| Unit | () | For functions with no return value |
String methods
| length() / is_empty() | Code-point count · emptiness |
| to_upper() / to_lower() / trim() | Case and whitespace |
| contains / starts_with / ends_with | Bool |
| split(sep) | List<String> |
| replace(old, new) / substring(start, end) | String (substring clamps out-of-range) |
| char_at(i) / index_of(needle) | Option<String> · Option<Int> |
| bytes() | List<Int>, the UTF-8 bytes |
List<T>
Mutable homogeneous list. Construct with [a, b, c] or by push. Index with xs[i] (unchecked) or get(i) (safe).
| length() / is_empty() / contains(x) | Int · Bool · Bool |
| push(x) | Append (mutation) |
| first() / last() / get(i) | Option<T> |
| map(f) / filter(p) / fold(init, f) | Transform · keep · reduce |
Ranges: a..b (exclusive) and a..=b (inclusive) produce a List<Int> and support the full List API. Float endpoints are excluded; a..b..c is a syntax error.
for i in 0..10 # 0, 1, ..., 9
stdio.println("${i}")
let evens = (0..10).filter(fun (x: Int) -> Bool => x % 2 == 0)Map<K, V>
Hash map. Construct via new_map() with a required type annotation.
| length() / is_empty() / contains_key(k) | Int · Bool · Bool |
| get(k) | Option<V> |
| set(k, v) | Insert / update (mutation) |
| keys() / values() / pairs() | List<K> · List<V> · List<(K, V)> |
Set<T>
Set of unique elements. Construct via new_set() with a type annotation.
| length() / is_empty() / contains(x) | Int · Bool · Bool |
| add(x) / remove(x) | No-op if duplicate / absent |
| to_list() | List<T> |
Option<T>
Built-in sum type Some(T) | None.
| is_some() / is_none() | Bool |
| unwrap_or(default) | T |
| map(f) / and_then(f) / filter(p) / or_else(f) | Option<…> |
| ok_or(err) | Result<T, E> |
Result<T, E>
Built-in sum type Ok(T) | Err(E). The ? operator propagates Err in functions that return Result.
| is_ok() / is_err() / unwrap_or(d) | Bool · Bool · T |
| map(f) / and_then(f) / map_err(f) / or_else(f) | Result<…> |
| ok() / err() | Option<T> · Option<E> |
JsonValue
Built-in sum type: JNull | JBool(Bool) | JNum(Float) | JStr(String) | JArr(List<JsonValue>) | JObj(Map<String, JsonValue>).
| is_null() | Bool |
| as_bool() / as_num() / as_string() | Option<Bool> · Option<Float> · Option<String> |
| as_array() / as_object() | Option<List<…>> · Option<Map<…>> |
| parse_json(s) / to_json(j) | Result<JsonValue, String> · String |
Conversions & panic
Capa has no implicit numeric coercion: Float + Int is a type error. Convert explicitly at the call site.
| parse_int(s) / parse_float(s) | Option<Int> · Option<Float> |
| to_float(i) / to_int(f) | Float · Int (truncates toward zero) |
| new_map() / new_set() | Require a let annotation to pin the types |
panic(message) terminates the program immediately: no unwinding, no catch. panic: <message> is written to stderr and the process exits non-zero. The contract is identical on every backend (Wasm and Component Model trap, translated to exit 1).
Python interoperability
Both functions cross the Capa/Python trust boundary and require Unsafe as the first argument. Crossing loses Capa's static guarantees: the Python value can do anything its type allows, with full ambient authority. --manifest marks such functions has_unsafe: true.
fun square_root(unsafe: Unsafe, x: Float) -> Float
let math = py_import(unsafe, "math")
return py_invoke(unsafe, math.sqrt, [x])Capabilities
Stdio
print(s), println(s), eprintln(s) (stderr), read_line() -> Result<String, IoError>.
Fs
| read(p) / write(p, c) | Result<String, IoError> · Result<(), IoError> |
| exists(p) / is_dir(p) | Bool (false on denied paths) |
| mkdir(p) / list_dir(p) | Result<(), …> · Result<List<String>, …> |
| restrict_to(prefix) / allows(path) | Attenuated Fs (monotonic) · query without I/O |
Env · Clock · Random
| env.get(name) / env.args() | Option<String> · List<String> |
| env.restrict_to_keys(keys) | Attenuated Env |
| clock.now_secs() / now_monotonic() / sleep(s) | Float · Float · () |
| clock.restrict_to_after(t) | Active only after timestamp (takes the maximum threshold) |
| random.int_range(low, high) / float_unit() | Int in [low,high) · Float in [0,1) |
| random.with_seed(seed) | Deterministic sequence |
Net
A Net from main is unrestricted; restrict_to(host) returns a fresh Net whose authority is the intersection with {host} (monotonic). get(url) returns Err immediately if the host is outside the restriction set, before any system call.
fun main(net: Net, stdio: Stdio)
let api = net.restrict_to("api.example.com")
match fetch(api)
Ok(body) -> stdio.println(body)
Err(e) -> stdio.eprintln("${e}")Db
SQLite-backed database with path-prefix attenuation (mirrors Fs). query returns the rows as a JSON-encoded array of arrays of strings, so the wire shape is a single form; callers parse with parse_json and project columns explicitly.
| exec(path, sql) | Result<(), IoError>, runs DDL / DML (multiple ;-separated statements supported) |
| query(path, sql) | Result<String, IoError>, JSON-encoded rows |
| restrict_to(prefix) / allows(path) | Attenuated Db (monotonic path prefix) · query without I/O |
Proc
Sandboxed subprocess execution with basename-prefix attenuation. exec takes the command and a JSON-encoded argv tail (for example ["status", "--short"]); stdout is returned as a String. allows checks the basename on a suffix boundary (restrict_to("git") admits git and git-lfs but not gitlab).
| exec(cmd, args_json) | Result<String, IoError>, the process stdout |
| restrict_to(cmd_prefix) / allows(cmd) | Attenuated Proc (basename prefix) · query without spawning |
User-defined capabilities
Libraries declare their own capabilities with the capability keyword; any type that impls it becomes a valid implementor. A cap-bearing struct may hold built-in caps as fields. Only call / method-call right-hand sides produce fresh capability instances that can be bound; a plain alias let dup = mailer is rejected.
capability SendEmail
fun send(self, to: String, subject: String, body: String) -> Result<Unit, IoError>
impl SendEmail for SmtpMailer
fun send(self, ...) -> Result<Unit, IoError>
return Ok(())The IoError type
Opaque type for I/O errors, available as the error parameter in Result<T, IoError> and in pattern matching. Its string representation is human-readable; the internal contents are private.
match fs.read("x.txt")
Ok(content) -> stdio.println(content)
Err(e) -> stdio.eprintln("error: ${e}")