Builtin Functions

Builtin Functions

Weave provides builtin functions for I/O, math, strings, file handling, serialization, HTTP, and more. Many builtins use a builder pattern: call with config to get a configured function back.

I/O

puts(value) – prints value to stdout with a trailing newline. Returns null.

print(value) – prints value to stdout without a newline. Returns null.

input() – reads one line from stdin (newline stripped). Returns string. Raises input_error.

print("Name: ")
name = input()
puts("Hello, {name}!")
puts([1, 2, 3])

Timing

clock() – returns current system time as nanoseconds since the Unix epoch. Raises io_error.

elapsed(start) – returns nanoseconds elapsed since a clock() reading. Raises io_error.

sleep(ms) – suspends execution for ms milliseconds. Returns null.

t = clock()
sleep(100)
puts("Took {elapsed(t)} ns")

Random

rand(seed?) – returns a pseudo-random number in [0.0, 1.0). Uses a Knuth LCG. If seed is null or omitted, seeds from system time.

x = rand()       # random each time
y = rand(42)     # deterministic: same seed = same result

Math

Rounding

ceil(n) – smallest integer >= n. floor(n) – largest integer <= n. round(n) – nearest integer.

ceil(1.2)   # 2
floor(1.8)  # 1
round(1.5)  # 2

Arithmetic

abs(n) – absolute value. min(a, b) – returns the smaller of two numbers. max(a, b) – returns the larger of two numbers. sqrt(n) – square root. pow(base, exp) – exponentiation. clamp(value, lo, hi) – clamps value to the range [lo, hi].

abs(-5)          # 5
min(3, 7)        # 3
max(3, 7)        # 7
sqrt(9)          # 3
pow(2, 10)       # 1024
clamp(15, 0, 10) # 10

Trigonometry and Logarithms

All trig functions work in radians.

sin(n), cos(n), tan(n) – trigonometric functions. ln(n) – natural logarithm. log10(n) – base-10 logarithm. exp(n) – exponential (e^n).

Strings

split(string, delimiter) – splits a string by delimiter. Returns a container of string parts. Supports pipeline usage – with one argument it returns a function awaiting the string.

split("a,b,c", ",")       # ["a", "b", "c"]
"a,b,c" |> split(",")     # ["a", "b", "c"] (pipeline form)

trim(s) – removes leading and trailing whitespace. ltrim(s) – removes leading whitespace. rtrim(s) – removes trailing whitespace. upper(s) – converts to uppercase. lower(s) – converts to lowercase. reverse(s) – reverses a string with full Unicode grapheme cluster awareness.

trim("  hello  ")   # "hello"
upper("hello")      # "HELLO"
lower("HELLO")      # "hello"
reverse("abc")      # "cba"

Type

type(value) – returns the type of a value as a symbol: :number, :string, :boolean, :null, :symbol, :container, :stream, or :function.

type(42)        # :number
type("hello")   # :string
type(true)      # :boolean
type([][0])     # :null
type(:foo)      # :symbol
type([1, 2])    # :container
type(puts)      # :function

to(target_type) – builder pattern. Returns a converter function for use in pipelines. Raises conversion_error on incompatible input.

"42" |> to(:number)       # 42
42 |> to(:string)         # "42"
[1, 2, 3] |> to(:stream)  # stream

Conversion rules:

Target Accepts
:number numbers, booleans (true->1, false->0), strings (parsed)
:string any value
:boolean booleans, numbers (0/NaN->false), null->false, strings/symbols (“true”/“false”)
:symbol symbols, strings, booleans, null
:container containers, streams (materialized), strings (split into graphemes)
:stream streams, containers (wrapped)

File I/O

open(path, mode) – opens a file. mode is :read, :write, or :append. Returns a handle container [handle: <number>, path: <string>, mode: <symbol>]. Raises file_not_found, permission_denied, io_error.

read(source, format?) – reads from a file path (string) or open handle. Optional format controls parsing:

  • Format symbols: :csv, :json, :jsonl, :yaml, :toml, :ini, :xml, :binary
  • Parser functions: pass any function that accepts a string and returns the parsed result
  • No format returns raw text. :csv and :jsonl return lazy streams. Other formats return parsed Weave values.
  • Raises file_not_found, permission_denied, io_error, parse_error.

write(dest, data, format?) – writes data to a file path or handle. Supports :csv, :json, :yaml, :toml, :ini, :xml. Returns null. Raises permission_denied, io_error, serialization_error.

close(handle) – closes a file or socket handle. Idempotent. Returns null.

text = read("notes.txt")
csv = read("data.csv", :csv)
config = read("config.json", :json)

write("out.txt", "hello")
write("data.json", my_data, :json)

f = open("log.txt", :append)
write(f, "entry\n")
close(f)

Containers

sort(container) – returns a new sorted container (ascending). Does not mutate the original.

Sort order: null < booleans < numbers < strings < symbols.

sort([3, 1, 2])   # [1, 2, 3]

Streams

Streams provide lazy, one-pass iteration over data. CSV and JSONL reads produce streams automatically.

stream(value) – wraps a container as a lazy stream. If already a stream, returns it as-is. Other values get wrapped in a single-element container first.

load(stream) – materializes a stream into a container. If already a container, returns it as-is. Raises stream_consumed.

head(source, n) – takes the first n elements from a stream or container. Returns a single value if n=1, a container if n>1, empty container if n=0. Raises stream_consumed.

s = stream([1, 2, 3, 4, 5])
first = head(s, 1)     # 1
next_two = head(s, 2)  # [2, 3]
rest = load(s)         # [4, 5]

Serialization

All parser and formatter builders follow the same pattern: call with optional config to get a function, then use that function with read/write or call it directly. See Custom Parsers for full configuration details.

Parsers

Function Config Description
csv_parser(config?) separator, headers, quote, escape, comment, trim Parses CSV text into row containers
json_parser() Parses JSON into Weave values
yaml_parser() Parses YAML into Weave values
toml_parser() Parses TOML into Weave values
ini_parser(config?) comment, delimiter Parses INI into section containers
xml_parser(config?) attr_prefix, text_key, collapse_text, trim_text Parses XML into container trees
html_parser(config?) attr_prefix, text_key, collapse_text, trim_text Forgiving HTML parser

Formatters

Function Config Description
csv_formatter(config?) separator, headers, quote Formats containers as CSV text
json_formatter(config?) pretty, indent Formats values as JSON text
yaml_formatter(config?) indent Formats values as YAML text
toml_formatter() Formats values as TOML text
ini_formatter(config?) delimiter Formats containers as INI text
xml_formatter(config?) attr_prefix, text_key, pretty, indent, root_name, declaration Formats values as XML text
# Parse CSV with a custom separator, write as pretty JSON
parse = csv_parser([separator: "\t"])
fmt = json_formatter([pretty: true])

data = read("data.tsv", parse)
write("data.json", data |> load(), fmt)

HTTP

http_client(config?) – builds a configured HTTP client. Config keys: base_url (string), headers (container), timeout (number, seconds). Returns a client function that accepts (method, path).

The response is a container with status (number), headers (container), body (string), and ok (boolean). Raises http_error (status >= 400), network_error.

client = http_client([base_url: "https://api.example.com"])
resp = client(:get, "/users")
puts(resp[:status])   # 200
puts(resp[:body])

Environment

env(name) – returns the value of environment variable name, or null if not set. args() – returns command-line arguments as a container of strings. cwd() – returns the current working directory. Raises io_error. chdir(path) – changes the working directory. Raises io_error.

home = env("HOME")
puts(cwd())
chdir("/tmp")
puts(args())

System

exit(code?) – terminates the process immediately. No cleanup runs. Default exit code is 0.

Deep Magic

These are low-level primitives prefixed with _. They’re wrapped by stdlib modules – use the high-level versions unless you need direct control.

Raw Byte I/O

_read(handle, n) – reads up to n raw bytes from an open file handle (max 16 MiB). Returns a container of byte values (0–255). Raises io_error.

_write(handle, bytes) – writes a container of raw bytes (0–255) to an open file handle. Returns the number of bytes written. Raises permission_denied, io_error.

Regex

The stdlib regex module wraps these primitives with a friendlier API. Use that unless you need the raw functions.

_regex_test(pattern, input) – tests whether pattern matches anywhere in input. Returns boolean. Raises regex_error.

_regex_exact(pattern, input) – tests whether pattern matches the entire input string. Returns boolean. Raises regex_error.

_regex_matches(pattern, input) – finds all matches of pattern in input. Returns a container of match containers, each with match (string), index (number), and groups (container). Raises regex_error.

_regex_test("\\d+", "abc123")            # true
_regex_exact("\\d+", "123")              # true
_regex_matches("(\\w+)", "hello world")  # [match containers...]

HTTP

_http_request(request) – sends a single HTTP request. The request container accepts keys: method (string, required), url (string, required), headers (container), body (string), timeout (number, seconds, default 30), base_url (string, prepended to url). Returns a container with status, headers, body, and ok. Raises http_error, network_error.

Sockets

The stdlib provides higher-level wrappers for networking. These primitives give you direct socket control when you need it.

TCP:

  • _socket(type) – creates a socket. type is :tcp or :udp. Returns [id: <number>, type: <symbol>, role: :unbound]. Raises socket_error.
  • _connect(handle, address, port, timeout?) – connects a TCP socket. timeout in ms. Raises connection_refused, connection_timeout, network_error.
  • _bind(handle, address, port) – binds to a local address and port. Raises socket_error.
  • _listen(handle, backlog?) – starts listening on a bound TCP socket. Raises socket_error.
  • _accept(handle, timeout?) – accepts a connection. timeout in ms. Raises accept_timeout, network_error.
  • _send(handle, data, timeout?) – sends data (string or byte container). timeout in ms. Returns bytes sent. Raises connection_closed, send_timeout, network_error.
  • _recv(handle, max_bytes, timeout?) – receives up to max_bytes (max 16 MiB). timeout in ms. Returns string (empty = closed). Raises recv_timeout, network_error.

UDP:

  • _sendto(handle, data, address, port, timeout?) – sends data to a specific address/port. Returns bytes sent. Raises send_timeout, network_error.
  • _recvfrom(handle, max_bytes, timeout?) – receives data with sender info. Returns [data: <string>, address: <string>, port: <number>]. Raises recv_timeout, network_error.
# TCP client example
sock = _socket(:tcp)
sock = _connect(sock, "example.com", 80, 5000)
_send(sock, "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n", null)
response = _recv(sock, 4096, 5000)
close(sock)

Evaluation

eval(code) – compiles and executes a string of Weave source code at runtime. Returns the result of evaluating the code.

eval("1 + 2")  # 3

expr = "pow(2, 8)"
eval(expr)     # 256