Libraries
Import Forms#
use os; // Import the whole library
// Import only the functions you will need
use { sqrt, pow } from math;
use { read_file, write_file } from fs;
Math Library
Type notes: Most math functions accept numeric values (either int or float). When a function returns a float, it returns float even if you pass int.
Constants:
math.PI,math.E,math.I
use math;
@println => |"PI: " + math.PI| // 3.141592653589793
@println => |"E: " + math.E| // 2.718281828459045
@println => |"I: " + math.I| // 0 + 1i
Functions:
math.sqrt => |x: numeric| -> float- Square root. #
use math;
let sqrt_val: float = math.sqrt => |16.0|; // 4.0
@println => |"sqrt(16): " + sqrt_val|
math.pow => |base: numeric, exp: numeric| -> float- Exponentiation. #
use math;
let pow_val: float = math.pow => |2.0, 8.0|; // 256.0
@println => |"pow(2, 8): " + pow_val|
math.abs => |x: numeric| -> numeric- Absolute value. #
use math;
let abs_val: float = math.abs => |-42.0|; // 42.0
@println => |"abs(-42): " + abs_val|
math.sin => |x: numeric| -> float- Sine (radians). #
use math;
let out: float = math.sin => |math.PI / 2.0|; // 1.0
@println => |out|
math.cos => |x: numeric| -> float- Cosine (radians). #
use math;
let out: float = math.cos => |0.0|; // 1.0
@println => |out|
math.tan => |x: numeric| -> float- Tangent (radians). #
use math;
let out: float = math.tan => |0.0|; // 0.0
@println => |out|
math.log => |x: numeric| -> float- Natural log. #
use math;
let out: float = math.log => |math.E|; // 1.0
@println => |out|
math.log => |x: numeric, base: numeric| -> float- Log with base. #
use math;
let out: float = math.log => |1000.0, 10.0|;
@println => |out|
math.exp => |x: numeric| -> float- Exponentiale^x. #
use math;
let exp_val: float = math.exp => |1.0|; // 2.7182818284590455
@println => |"exp(1): " + exp_val|
math.floor => |x: numeric| -> float- Largest integer <= x (returned as float). #
use math;
let floor_val: float = math.floor => |3.9|; // 3.0
@println => |"floor(3.9): " + floor_val|
math.ceil => |x: numeric| -> float- Smallest integer >= x (returned as float). #
use math;
let ceil_val: float = math.ceil => |3.1|; // 4.0
@println => |"ceil(3.1): " + ceil_val|
math.round => |x: numeric| -> float- Rounded value (returned as float). #
use math;
let round_val: float = math.round => |3.6|; // 4.0
@println => |"round(3.6): " + round_val|
math.min => |a: numeric, b: numeric| -> numeric- Minimum of two numbers. #
use math;
let min_val: float = math.min => |7.5, 2.25|; // 2.25
@println => |"min(7.5, 2.25): " + min_val|
math.max => |a: numeric, b: numeric| -> numeric- Maximum of two numbers. #
use math;
let max_val: float = math.max => |7.5, 2.25|; // 7.5
@println => |"max(7.5, 2.25): " + max_val|
math.clamp => |x: numeric, min: numeric, max: numeric| -> numeric- Clamp number to range. #
use math;
let clamp_val: float = math.clamp => |12.0, 0.0, 10.0|; // 10.0
@println => |"clamp(12, 0, 10): " + clamp_val|
let clamp_val: float = math.clamp => |-12.0, 0.0, 10.0|; // 0.0
@println => |"clamp(-12, 0, 10): " + clamp_val|
math.random => || -> float- Pseudo-random float in[0.0, 1.0). #
use math;
let rand_val: float = math.random => ||;
@println => |"random(): " + rand_val|
math.rand_int => |min: int, max: int| -> int- Random integer in inclusive range. #
use math;
let rand_int_val: int = math.rand_int => |1, 10|;
@println => |"rand_int(1, 10): " + rand_int_val|
math.rand_choice => |arr: arr| -> any- Random element from a non-empty array. #
use math;
let choice_val: int = math.rand_choice => |[10, 20, 30, 40]|;
@println => |"rand_choice([10,20,30,40]): " + choice_val|
math.shuffle => |arr: arr| -> arr- Returns a shuffled copy of an array. #
use math;
let shuffled_vals: arr = math.shuffle => |[1, 2, 3, 4, 5]|;
@println => |"shuffle([1,2,3,4,5]): " + shuffled_vals|
math.atan2 => |y: numeric, x: numeric| -> float- Angle from X-axis to (x, y). #
use math;
let atan2_val: float = math.atan2 => |1.0, 1.0|;
@println => |"atan2(1, 1): " + atan2_val|
math.vector => |arr: arr| -> arr- Convert numeric array to a vector value. #
use math;
let vector: arr = math.vector => |[1, 2, 3]|;
@println => |"vector: " + vector|
math.dot => |a: arr, b: arr| -> float- Dot product of vectors/arrays. #
use math;
let v1: arr = math.vector => |[1, 2, 3]|;
let v2: arr = math.vector => |[4, 5, 6]|;
let dot_val: float = math.dot => |v1, v2|; // 1*4 + 2*5 + 3*6 = 32 all floats
@println => |"dot(v1, v2): " + dot_val|
math.matrix => |arr: arr| -> arr- Validate/create matrix-like array. #
use math;
let m1: arr = math.matrix => |[[1, 2], [3, 4]]|;
let m2: arr = math.matrix => |[[5, 6], [7, 8]]|;
@println => |"m1: " + m1|
@println => |"m2: " + m2|
math.matmul => |a: arr, b: arr| -> arr- Matrix multiplication. #
use math;
let m1: arr = [[1.0, 2.0], [3.0, 4.0]];
let m2: arr = [[5.0], [6.0]];
let out: arr = math.matmul => |m1, m2|;
FS (File System) Library
All paths are string. Most functions throw a runtime error if the operation fails (missing file, permissions, invalid path, etc.).
Functions:
fs.read_file => |path: string| -> string- Read file contents as a string. #
use fs;
let file_path: string = "data.txt";
let data: string = fs.read_file => |file_path|;
@println => |"File data: " + data|
fs.write_file => |path: string, content: string| -> void- Write a string to a file. #
use fs;
let file_path: string = "data.txt";
fs.write_file => |file_path, "This is some text"|
fs.append_file => |path: string, content: string| -> void- Append a string to a file. #
use fs;
fs.append_file => |file_path, "\nThis is some more text."|
fs.read_dir => |path: string| -> arr- Read directory entries (file/dir names). #
use fs;
let dir_entries: arr = fs.read_dir => |"tests"|;
@println => |"Read dir entries: " + dir_entries|
fs.read_lines => |path: string| -> arr- Read file line-by-line as a string array. #
use fs;
let lines: arr = fs.read_lines => |file_path|;
@println => |"Read lines: " + lines|
fs.create_dir => |path: string| -> void- Create a directory tree. #
use fs;
let dir_path: string = "test_dir";
fs.create_dir => |dir_path|
fs.remove_dir => |path: string| -> void- Remove a directory tree. #
use fs;
let dir_path: string = "test_dir";
fs.remove_dir => |dir_path|
fs.exists => |path: string| -> bool- Check whether a path exists. #
use fs;
let dir_path: string = "test_dir";
let dir_exists: bool = fs.exists => |dir_path|;
@println => |"Dir exists: " + dir_exists|
fs.is_file => |path: string| -> bool- Check whether a path is a file. #
use fs;
let file_path: string = "data.txt";
let path_is_file: bool = fs.is_file => |file_path|;
@println => |"Is file: " + path_is_file|
fs.is_dir => |path: string| -> bool- Check whether a path is a directory. #
use fs;
let dir_path: string = "test_dir";
let path_is_dir: bool = fs.is_dir => |dir_path|;
@println => |"Is dir: " + path_is_dir|
fs.remove_file => |path: string| -> void- Delete a file. #
use fs;
let file_path: string = "data.txt";
fs.remove_file => |file_path|
fs.copy_file => |src: string, dst: string| -> int- Copy a file and return bytes copied. #
use fs;
let file_path: string = "data.txt";
let copy_path: string = "data_copy.txt";
let copied_bytes: int = fs.copy_file => |file_path, copy_path|;
@println => |"Bytes copied: " + copied_bytes|
fs.rename => |src: string, dst: string| -> void- Rename/move a path. #
use fs;
let copy_path: string = "data_copy.txt";
let moved_path: string = "data_moved.txt";
fs.rename => |copy_path, moved_path|
fs.stat => |path: string| -> obj- Metadata: size, type, readonly, modified time (unix ms). #
use fs;
let file_path: string = "data.txt";
let stats: obj = fs.stat => |file_path|;
OS (Operating System) Library
These functions expose OS/process info. Some features can be disabled at runtime (for example, command execution).
Functions:
os.cwd => || -> string- Current working directory. #
use os;
let cwd: string = os.cwd => ||;
@println => |"Current directory: " + cwd|
os.ls => |path: string| -> arr- List directory entries (defaults to"."). #
use os;
let files: arr = os.ls => |"./images"|;
@println => |"Files: " + files|
os.env => |key: string| -> string- Read an environment variable (empty string if missing). #
use os;
let env_val: string = os.env => |"ZK_TEST_VAR"|;
@println => |"ZK_TEST_VAR: " + env_val|
os.set_env => |key: string, value: string| -> void- Set an environment variable. #
use os;
os.set_env => |"ZK_TEST_VAR", "hello"|
os.remove_env => |key: string| -> void- Remove an environment variable. #
use os;
os.remove_env => |"ZK_TEST_VAR"|
os.platform => || -> string- Platform string ("linux","windows", etc.). #
use os;
let plat: string = os.platform => ||;
@println => |"Platform: " + plat|
os.args => || -> arr- Command-line argument array. #
use os;
let args: arr = os.args => ||;
@println => |"Args: " + args|
os.home_dir => || -> string- User home directory path (empty string if unknown). #
use os;
let home: string = os.home_dir => ||;
@println => |"Home directory: " + home|
os.temp_dir => || -> string- System temporary directory path. #
use os;
let temp: string = os.temp_dir => ||;
@println => |"Temp directory: " + temp|
os.hostname => || -> string- Host name (empty string if unavailable). #
use os;
let host: string = os.hostname => ||;
@println => |"Hostname: " + host|
os.username => || -> string- Current user name (empty string if unavailable). #
use os;
let user: string = os.username => ||;
@println => |"Username: " + user|
os.arch => || -> string- CPU architecture string. #
use os;
let arch: string = os.arch => ||;
@println => |"Arch: " + arch|
os.cpu_count => || -> int- Logical CPU count. #
use os;
let cpu_count: int = os.cpu_count => ||;
@println => |"CPU Count: " + cpu_count|
os.uptime_ms => || -> int- Uptime in milliseconds (Linux only). #
use os;
let uptime: int = os.uptime_ms => ||;
@println => |"Uptime (ms): " + uptime|
os.which => |cmd: string| -> string- Resolve an executable path (empty string if not found). #
use os;
let which_echo: string = os.which => |"echo"|;
@println => |"which echo: " + which_echo|
os.exit => |code: int| -> never- Exit the runtime with an optional code (CLI). #
use os;
os.exit => |0|
os.pid => || -> int- Current process id. #
use os;
let pid: int = os.pid => ||;
@println => |"Process ID: " + pid|
os.sleep => |ms: int| -> void- Sleep for milliseconds. #
use os;
@println => |"Sleeping for 2 seconds..."|
os.sleep => |2000| // Sleep for 2 seconds
@println => |"Slept for 2 seconds"|
os.exec => |cmd: string, args: arr| -> obj- Execute a command and capture{status, stdout, stderr}. #
use os;
let exec_result: obj = os.exec => |"echo", ["Hello, World!"]|;
@println => |"Exec status: " + exec_result.status|
@println => |"Exec stdout: " + exec_result.stdout|
@println => |"Exec stderr: " + exec_result.stderr|
os.system => |cmd: string, args: arr| -> int- Execute a command inheriting stdio and return exit code. #
use os;
let system_status: int = os.system => |"echo", ["Hello, World!"]|;
@println => |"system.status: " + system_status|
os.spawn => |cmd: string, args: arr| -> int- Spawn a process and return pid. #
use os;
let spawn_pid: int = os.spawn => |"sleep", ["0.1"]|;
@println => |"spawn.pid: " + spawn_pid|
Encoding Library
Encoding helpers operate on string input and return string output. Decode functions throw a runtime error on invalid input.
Functions:
encoding.base64_encode => |input: string| -> string- Base64-encode a string. #
use encoding;
let out: string = encoding.base64_encode => |"Hello, Zekken!"|;
@println => |out|
encoding.base64_decode => |input: string| -> string- Base64-decode into a UTF-8 string. #
use encoding;
let decoded: string = encoding.base64_decode => |"SGVsbG8sIFpla2tlbiE="|;
@println => |decoded|
encoding.hex_encode => |input: string| -> string- Hex-encode string bytes. #
use encoding;
let out: string = encoding.hex_encode => |"ABC123"|;
@println => |out|
encoding.hex_decode => |input: string| -> string- Hex-decode into a UTF-8 string. #
use encoding;
let decoded: string = encoding.hex_decode => |"414243313233"|;
@println => |decoded|
encoding.url_encode => |input: string| -> string- Percent-encode a string for URLs. #
use encoding;
let out: string = encoding.url_encode => |"hello world?x=1&y=2"|;
@println => |out|
encoding.url_decode => |input: string| -> string- Percent-decode a string. #
use encoding;
let decoded: string = encoding.url_decode => |"hello%20world%3Fx%3D1%26y%3D2"|;
@println => |decoded|
Path Library
Cross-platform path helpers. All inputs and outputs are string.
Functions:
path.join => |...parts: string| -> string- Join path segments. You can pass multiple strings, or one array of strings. #
use path;
let p: string = path.join => |"tests", "libraries", "os.zk"|;
@println => |p|
path.normalize => |path: string| -> string- Normalize.and..segments. #
use path;
let out: string = path.normalize => |"a/./b/../c"|;
@println => |out|
path.resolve => |...parts: string| -> string- Resolve to an absolute normalized path. With no args, returns the current working directory. #
use path;
let out: string = path.resolve => |"tests", ".."|;
@println => |out|
path.basename => |path: string| -> string- Final path component. #
use path;
let out: string = path.basename => |"tests/libraries/os.zk"|;
@println => |out|
path.dirname => |path: string| -> string- Parent directory ("."when unknown). #
use path;
let out: string = path.dirname => |"tests/libraries/os.zk"|;
@println => |out|
path.extname => |path: string| -> string- File extension including leading dot (".txt"). #
use path;
let out: string = path.extname => |"tests/libraries/os.zk"|;
@println => |out|
path.stem => |path: string| -> string- File name without extension. #
use path;
let out: string = path.stem => |"tests/libraries/os.zk"|;
@println => |out|
path.is_abs => |path: string| -> bool- Whether the path is absolute. #
use path;
let out: bool = path.is_abs => |"/tmp"|;
@println => |out|
path.relative => |from: string, to: string| -> string- Relative path fromfromtoto. #
use path;
let out: string = path.relative => |"tests", "tests/libraries/os.zk"|;
@println => |out|
HTTP Library
HTTP client and server helpers. On WASM builds, HTTP is disabled. On native builds, you can disable it with ZEKKEN_DISABLE_HTTP=1.
Client
http.request => |method: string, url: string, headers: obj, body: any, timeout_ms: int| -> obj- Returns{url, status, ok, headers, body}. #
use http;
// Native runtime only (HTTP is disabled in WASM builds).
let resp: obj = http.request => |"GET", "https://example.com"|;
@println => |resp.status|
use http;
// Native runtime only.
let resp: obj = http.get => |"https://example.com"|;
@println => |resp.ok|
use http;
// Native runtime only.
let resp: obj = http.post => |"https://example.com", "hello"|;
@println => |resp.status|
http.get_json => |url: string, headers: obj, timeout_ms: int| -> any- GET + parse JSON response body. #
use http;
// Native runtime only.
let data: any = http.get_json => |"https://example.com/data.json"|;
@println => |data|
http.build_query => |params: obj| -> string- Buildk=v&k2=v2query strings. #
use http;
let qs: string = http.build_query => |{ a: 1, b: "two" }|;
@println => |qs|
http.parse_query => |qs: string| -> obj- Parse a query string into an object of strings. #
use http;
let obj: obj = http.parse_query => |"a=1&b=two"|;
@println => |obj|
Server
http.serve => |addr: string, routes: obj| -> void- Simple static routing. Route keys can be"/path"or"METHOD /path". Use"__default__"as a fallback. #
use http;
// Native runtime only.
let html: string = "<!doctype html><h1>Zekken HTTP</h1>";
let routes: obj = {
"/": { status: 200, headers: { "content-type": "text/html; charset=utf-8" }, body: html }
};
http.serve => |"127.0.0.1:8080", routes|
http.listen => |addr: string| -> obj- Low-level server that returns an object withaccept,respond, andaddr. #
use http;
// Native runtime only.
let server: obj = http.listen => |"127.0.0.1:8080"|;
@println => |"listening on: " + (server.addr => ||)|