Skip to content

Standard Library Reference

This is the complete reference for all built-in functions and methods available in every Kōdo program without explicit imports.

Prints a string to stdout followed by a newline.

println("Hello, world!")

Prints a string to stdout without a trailing newline.

print("Enter name: ")

Prints an integer to stdout.

print_int(42)

Prints a float to stdout without a newline.

print_float(3.14)

Prints a float to stdout followed by a newline.

println_float(2.718)

Reads one line from stdin and returns it as a string.

let name: String = readln()

Returns the command-line arguments as a list of strings.

let argv: List<String> = args()
let first: String = list_get(argv, 0)

Exits the process with the given exit code.

exit(1)

Returns the absolute value of x.

let n: Int = abs(-5) // 5

Returns the smaller of two integers.

let m: Int = min(3, 7) // 3

Returns the larger of two integers.

let m: Int = max(3, 7) // 7

Clamps x to the range [lo, hi].

let c: Int = clamp(50, 0, 25) // 25

Returns a random integer in the range [min, max].

let r: Int = rand_int(1, 100)

Returns the square root of x.

let s: Float64 = sqrt(9.0) // 3.0

pow(base: Float64, exp: Float64) -> Float64

Section titled “pow(base: Float64, exp: Float64) -> Float64”

Returns base raised to the power exp.

let p: Float64 = pow(2.0, 10.0) // 1024.0

Returns the sine of x (in radians).

let s: Float64 = sin(3.14159)

Returns the cosine of x (in radians).

let c: Float64 = cos(0.0) // 1.0

Returns the natural logarithm of x.

let l: Float64 = log(2.718) // ~1.0

Rounds x down to the nearest integer.

let f: Float64 = floor(3.7) // 3.0

Rounds x up to the nearest integer.

let c: Float64 = ceil(3.2) // 4.0

Rounds x to the nearest integer.

let r: Float64 = round(3.5) // 4.0

String methods are called with dot syntax on string values.

Returns the number of Unicode code points (characters) in the string. For ASCII-only strings this equals the byte length.

let len: Int = "hello".length() // 5

Returns true if the string contains substr.

let has: Bool = "hello world".contains("world") // true

Returns true if the string starts with prefix.

let yes: Bool = "hello".starts_with("hel") // true

Returns true if the string ends with suffix.

let yes: Bool = "hello".ends_with("llo") // true

Returns a copy with leading and trailing whitespace removed.

let t: String = " hello ".trim() // "hello"

Returns an uppercase copy of the string.

let u: String = "hello".to_upper() // "HELLO"

Returns a lowercase copy of the string.

let l: String = "HELLO".to_lower() // "hello"

s.substring(start: Int, end: Int) -> String

Section titled “s.substring(start: Int, end: Int) -> String”

Extracts a substring from character index start to end (exclusive). Indices are Unicode code point positions, so multi-byte characters (accented letters, CJK, emoji) are handled correctly. Out-of-range indices are clamped.

let sub: String = "hello".substring(1, 4) // "ell"

Returns the number of UTF-8 bytes in the string (as opposed to length() which returns the number of characters).

let bl: Int = "héllo".byte_length() // 6 (é is 2 bytes)

Returns the number of Unicode code points in the string. This is an alias for length().

let cc: Int = "héllo".char_count() // 5

Splits the string by sep and returns a list of parts.

let parts: List<String> = "a,b,c".split(",")
// parts contains ["a", "b", "c"]

Splits the string by newline characters.

let ls: List<String> = "line1\nline2".lines()

Returns the byte value at the given index.

let ch: Int = "ABC".char_at(0) // 65

Returns the string repeated count times.

let r: String = "ab".repeat(3) // "ababab"

Parses the string as an integer. Returns 0 on failure.

let n: Int = "42".parse_int() // 42

Converts an integer to its string representation.

let s: String = 42.to_string() // "42"

Converts an integer to a Float64.

let f: Float64 = 42.to_float64() // 42.0

Converts a float to its string representation.

let s: String = 3.14.to_string()

Truncates a float to an integer (toward zero).

let n: Int = 3.7.to_int() // 3

Converts a boolean to "true" or "false".

Not yet implemented. Use if b { "true" } else { "false" } as a workaround.

file_read(path: String) -> Result<String, String>

Section titled “file_read(path: String) -> Result<String, String>”

Reads the entire contents of a file.

let content: Result<String, String> = file_read("data.txt")

file_write(path: String, content: String) -> Result<Unit, String>

Section titled “file_write(path: String, content: String) -> Result<Unit, String>”

Writes content to a file, overwriting any existing content.

let r: Result<Unit, String> = file_write("out.txt", "hello")

file_append(path: String, content: String) -> Result<Unit, String>

Section titled “file_append(path: String, content: String) -> Result<Unit, String>”

Appends content to a file.

let r: Result<Unit, String> = file_append("log.txt", "new line\n")

Deletes a file. Returns true on success.

Not yet linked in runtime. Will produce a link error at build time.

let ok: Bool = file_delete("temp.txt")

Checks if a file exists.

let exists: Bool = file_exists("config.json")

Lists the contents of a directory.

let entries: List<String> = dir_list(".")

Checks if a directory exists.

let exists: Bool = dir_exists("src/")

Lists are created and manipulated via free functions. Methods like .iter(), .map(), .filter() are available as dot-syntax on list values.

Creates a new empty list. The element type is inferred from the type annotation:

let nums: List<Int> = list_new()
let names: List<String> = list_new()

Note: List<String> passes type checking. Some codegen operations on string lists (e.g., println(list_get(names, 0))) may require string interpolation as a workaround.

Appends a value to the end of the list.

list_push(nums, 42)

Returns the element at the given index.

let first: Int = list_get(nums, 0)

Returns the number of elements in the list.

let len: Int = list_length(nums)

list_contains(list: List<T>, value: T) -> Bool

Section titled “list_contains(list: List<T>, value: T) -> Bool”

Returns true if the list contains the value.

let has: Bool = list_contains(nums, 42)

Removes and returns the last element.

Not yet linked in runtime. Will produce a link error at build time.

let last: Int = list_pop(nums)

list_remove(list: List<T>, index: Int) -> Bool

Section titled “list_remove(list: List<T>, index: Int) -> Bool”

Removes the element at the given index. Returns true on success.

let ok: Bool = list_remove(nums, 0)

list_set(list: List<T>, index: Int, value: T) -> Bool

Section titled “list_set(list: List<T>, index: Int, value: T) -> Bool”

Sets the element at the given index. Returns true on success.

let ok: Bool = list_set(nums, 0, 99)

Returns true if the list has no elements.

let empty: Bool = list_is_empty(nums)

Reverses the list in place.

list_reverse(nums)

These are called as methods on list values:

MethodSignatureDescription
list.slice(start, end)(Int, Int) -> List<T>Extract a sub-list
list.sort()() -> UnitSort in place (ascending)
list.join(sep)(String) -> StringJoin elements with separator (for List<String>)
list.iter()() -> IteratorCreate an iterator for for-in or combinators
list.map(f)((T) -> U) -> List<U>Transform each element
list.filter(f)((T) -> Bool) -> List<T>Keep elements matching predicate
list.fold(init, f)(U, (U, T) -> U) -> UReduce to a single value
list.count()() -> IntCount elements
list.any(f)((T) -> Bool) -> BoolTrue if any element matches
list.all(f)((T) -> Bool) -> BoolTrue if all elements match

Maps support Int and String as key and value types, in any combination. The type is determined by the annotation on the let binding.

Creates a new empty map.

let scores: Map<String, Int> = map_new()

map_insert(map: Map<K, V>, key: K, value: V)

Section titled “map_insert(map: Map<K, V>, key: K, value: V)”

Inserts or updates a key-value pair.

map_insert(scores, "alice", 95)

Returns the value associated with the key.

let score: Int = map_get(scores, "alice")

map_contains_key(map: Map<K, V>, key: K) -> Bool

Section titled “map_contains_key(map: Map<K, V>, key: K) -> Bool”

Returns true if the key exists.

let has: Bool = map_contains_key(scores, "alice")

Returns the number of entries.

let n: Int = map_length(scores)

map_remove(map: Map<K, V>, key: K) -> Bool

Section titled “map_remove(map: Map<K, V>, key: K) -> Bool”

Removes the entry with the given key. Returns true on success.

let ok: Bool = map_remove(scores, "alice")

Returns 1 if the map has no entries, 0 otherwise.

let empty: Int = map_is_empty(scores)

Use for-in to iterate over Map keys:

let m: Map<Int, Int> = map_new()
map_insert(m, 1, 100)
map_insert(m, 2, 200)
for key in m {
print_int(key)
}

You can also use map_contains_key and map_get for direct lookups:

if map_contains_key(m, 1) {
print_int(map_get(m, 1)) // 100
}

Parses a JSON string and returns an opaque handle.

let doc: Int = json_parse("{\"name\": \"alice\"}")

json_get_string(handle: Int, key: String) -> String

Section titled “json_get_string(handle: Int, key: String) -> String”

Extracts a string field from a JSON object.

let name: String = json_get_string(doc, "name") // "alice"

json_get_int(handle: Int, key: String) -> Int

Section titled “json_get_int(handle: Int, key: String) -> Int”

Extracts an integer field.

let age: Int = json_get_int(doc, "age")

json_get_bool(handle: Int, key: String) -> Int

Section titled “json_get_bool(handle: Int, key: String) -> Int”

Extracts a boolean field. Returns 1 for true, 0 for false, -1 if not found.

let active: Int = json_get_bool(doc, "active")

json_get_float(handle: Int, key: String) -> Float64

Section titled “json_get_float(handle: Int, key: String) -> Float64”

Extracts a float field.

let score: Float64 = json_get_float(doc, "score")

json_get_array(handle: Int, key: String) -> List<Int>

Section titled “json_get_array(handle: Int, key: String) -> List<Int>”

Extracts an array field as a list of JSON handles.

let items: List<Int> = json_get_array(doc, "items")

json_get_object(handle: Int, key: String) -> Int

Section titled “json_get_object(handle: Int, key: String) -> Int”

Extracts a nested JSON object as a handle.

let nested: Int = json_get_object(doc, "metadata")

Releases memory associated with a JSON handle.

json_free(doc)

Serializes a JSON handle back to a JSON string.

let text: String = json_stringify(doc)

Creates a new empty JSON object and returns a handle.

let obj: Int = json_new_object()

json_set_string(handle: Int, key: String, value: String)

Section titled “json_set_string(handle: Int, key: String, value: String)”

Sets a string field on a JSON object.

json_set_string(obj, "name", "alice")

json_set_int(handle: Int, key: String, value: Int)

Section titled “json_set_int(handle: Int, key: String, value: Int)”

Sets an integer field.

json_set_int(obj, "age", 30)

json_set_bool(handle: Int, key: String, value: Bool)

Section titled “json_set_bool(handle: Int, key: String, value: Bool)”

Sets a boolean field.

json_set_bool(obj, "active", true)

json_set_float(handle: Int, key: String, value: Float64)

Section titled “json_set_float(handle: Int, key: String, value: Float64)”

Sets a float field.

json_set_float(obj, "score", 9.5)

Returns the current Unix timestamp in seconds.

let ts: Int = time_now()

Returns the current Unix timestamp in milliseconds.

let ms: Int = time_now_ms()

Formats a Unix timestamp as an ISO 8601 string.

let formatted: String = time_format(time_now())

Returns the number of milliseconds elapsed since start.

let start: Int = time_now_ms()
// ... work ...
let elapsed: Int = time_elapsed_ms(start)

Returns the value of an environment variable.

let home: String = env_get("HOME")

Sets an environment variable.

env_set("MY_VAR", "value")

Channels provide typed communication between spawned tasks. Currently limited to Int, Bool, and String types.

let ch: Channel<Int> = channel_new()
channel_send(ch, 42)
let val: Int = channel_recv(ch)
channel_free(ch)
let ch: Channel<Bool> = channel_new_bool()
channel_send_bool(ch, true)
let val: Bool = channel_recv_bool(ch)
let ch: Channel<String> = channel_new_string()
channel_send_string(ch, "hello")
let val: String = channel_recv_string(ch)

Releases a channel’s resources.

http_get(url: String) -> Result<String, String>

Section titled “http_get(url: String) -> Result<String, String>”

Performs an HTTP GET request and returns the response body.

let resp: Result<String, String> = http_get("https://api.example.com/data")

http_post(url: String, body: String) -> Result<String, String>

Section titled “http_post(url: String, body: String) -> Result<String, String>”

Performs an HTTP POST request with the given body.

let resp: Result<String, String> = http_post("https://api.example.com/data", "{\"key\": \"value\"}")

Creates an HTTP server listening on the given port. Returns a server handle.

let server: Int = http_server_new(8080)

Waits for an incoming HTTP request. Returns a request handle.

let req: Int = http_server_recv(server)

http_request_method(request: Int) -> String

Section titled “http_request_method(request: Int) -> String”

Returns the HTTP method (e.g., "GET", "POST").

let method: String = http_request_method(req)

Returns the request URL path.

let path: String = http_request_path(req)

Returns the request body.

let body: String = http_request_body(req)

http_respond(request: Int, status: Int, body: String)

Section titled “http_respond(request: Int, status: Int, body: String)”

Sends an HTTP response with the given status code and body.

http_respond(req, 200, "{\"status\": \"ok\"}")

Closes the HTTP server and releases resources.

http_server_free(server)

Opens a SQLite database and returns a handle.

let db: Int = db_open("app.db")

Executes a SQL statement. Returns 0 on success, 1 on error.

let ok: Int = db_execute(db, "CREATE TABLE users (id INTEGER, name TEXT)")

Executes a query and returns a result handle.

let result: Int = db_query(db, "SELECT * FROM users")

Returns 1 if there is a next row, 0 if exhausted.

let has_row: Int = db_row_next(result)

db_row_get_string(result: Int, col: Int) -> String

Section titled “db_row_get_string(result: Int, col: Int) -> String”

Returns a string column value from the current row.

let name: String = db_row_get_string(result, 1)

db_row_get_int(result: Int, col: Int) -> Int

Section titled “db_row_get_int(result: Int, col: Int) -> Int”

Returns an integer column value from the current row.

let id: Int = db_row_get_int(result, 0)

Advances to the next row. Returns 1 if successful, 0 if done.

let more: Int = db_row_advance(result)

Releases a query result set.

db_result_free(result)

Closes the database connection.

db_close(db)

Returns true if the option contains a value.

let x: Option<Int> = Option::Some(42)
let yes: Bool = x.is_some() // true

Returns true if the option is None.

let x: Option<Int> = Option::None
let yes: Bool = x.is_none() // true

Returns the contained value, or default if None.

let x: Option<Int> = Option::None
let val: Int = x.unwrap_or(0) // 0

Returns true if the result is Ok.

let r: Result<Int, String> = Result::Ok(42)
let yes: Bool = r.is_ok() // true

Returns true if the result is Err.

let r: Result<Int, String> = Result::Err("failed")
let yes: Bool = r.is_err() // true

Returns the Ok value, or default if Err.

let r: Result<Int, String> = Result::Err("oops")
let val: Int = r.unwrap_or(0) // 0

These functions are available inside test blocks.

FunctionSignatureDescription
assert(condition)(Bool)Fails if false
assert_true(condition)(Bool)Fails if false (alias for assert)
assert_false(condition)(Bool)Fails if true
assert_eq(left, right)(T, T)Fails if left != right
assert_ne(left, right)(T, T)Fails if left == right

assert_eq and assert_ne support Int, String, Bool, and Float64.