Skip to content
Logos / Builtins

Builtins Reference

Logos built-in functions. Use try for error handling on functions marked (try).

Try Expressions v0.4

Functions marked (try) return {ok, value, error}. Use try to unwrap and propagate errors:

Functions that return result tables:

  • File I/O: fileRead, fileWrite, fileAppend, fileDelete, fileMkdir, fileReadDir, fileGlob, fileCopy, fileMove
  • System: run, shell
  • JSON: parseJson, toJson, prettyJson
  • HTTP: httpGet, httpPost, httpPut, httpPatch, httpDelete
logos
// Verbose error checking:
let res = fileRead("data.json")
if !res.ok { return res.error }
let data = res.value

// With try (v0.4+):
let data = try fileRead("data.json")

Try + Pipe v0.4

logos
// Modern error handling with try + pipe (v0.4)
// Errors propagate automatically through the chain

// Fetch and transform user data
fn getUserStats(id) {
    return try httpGet("https://api.example.com/users/" + str(id))
        |> try parseJson
        |> map(fn(u) -> table{
            name: u.name,
            email: u.email,
            score: u.score,
        })
}

// Safe file processing pipeline
fn processFile(path) {
    return try fileRead(path)
        |> try parseJson
        |> filter(fn(d) -> d.active)
        |> map(fn(d) -> d.name)
}

// Chained JSON operations
let config = try fileRead("config.json")
    |> try parseJson
    |> filter(fn(c) -> c.enabled)
    |> map(fn(c) -> c.settings)

I/O

print(args...) Prints all args with trailing newline (v0.4.5)
printn(args...) Prints without trailing newline (v0.4.5)
input(prompt?) Reads line from stdin, optional prompt
prompt(msg) Shows message, waits for input
confirm(msg) Shows (y/n), returns bool
select(msg, opts) Numbered menu, returns choice
clear() Clears terminal screen
logos
// print() - outputs with trailing newline (v0.4.5, default)
// printn() - outputs without trailing newline (v0.4.5)
print("Hello!")
printn("No newline")
print("Next line")

// input() - reads one line from user (no prompt)
let name = input()
print("You typed: " + name)

// prompt(message) - shows message AND reads input
let age = prompt("Enter your age: ")
print("You are " + age)

// confirm() - yes/no question, returns true/false
if confirm("Delete all files?") {
    print("Deleted!")
}

// select() - numbered menu, returns chosen value
let choice = select("Pick a color:", ["red", "green", "blue"])
print("You chose: " + choice)

	// clear() - clear the terminal
	clear()

confirm()

logos
if confirm("Delete this file?") {
    print("Deleting...")
    try fileDelete("data.txt")
} else {
    print("Cancelled")
}

select()

logos
let choice = select("Pick a color:", ["red", "green", "blue"])

if choice == "red" {
    print(colorRed("You picked red"))
} else if choice == "green" {
    print(colorGreen("You picked green"))
}

Color Output

colorRed(s) Red text
colorGreen(s) Green text
colorYellow(s) Yellow text
colorBlue(s) Blue text
colorBold(s) Bold text
logos
print(colorRed("Error"))
print(colorGreen("Success"))
print(colorBold(colorYellow("Warning")))

Type Functions

type(value) Returns type name string
len(value) Length of string/array/table

File Operations try

fileRead(path) Read file (try)
fileWrite(path, data) Write file (try)
fileAppend(path, data) Append to file (try)
fileExists(path) Check if exists (bool)
fileDelete(path) Delete file (try)
fileMkdir(path) Create dir (try)
fileReadDir(path) List dir (try)
fileGlob(pattern) Glob files (try)
fileCopy(src, dst) Copy file (try)
fileMove(src, dst) Move file (try)
logos
// File functions return {ok, value, error}
// Use try to unwrap and propagate errors (v0.4+)

let content = try fileRead("config.json")
print("File has ${len(content)} characters")

let written = try fileWrite("output.txt", "Hello, World!")
print("Written: ${written}")

try fileAppend("log.txt", "New log entry\n")

if fileExists("data.json") {
    let data = try fileRead("data.json")
    print(data)
}

try fileMkdir("backup/2024/january")

let files = try fileReadDir(".")
for item in files {
    print("Found: " + item)
}

let globRes = try fileGlob("*.lgs")
for script in globRes {
    print("Script: " + script)
}

String Operations

upper(s) Uppercase
lower(s) Lowercase
trim(s) Remove whitespace
replace(s, old, new) Replace all
split(s, sep) Split into array
join(arr, sep) Join with separator
contains(s, sub) Check substring
indexOf(s, sub) Find index (-1 if none)
startsWith(s, prefix) Check prefix
endsWith(s, suffix) Check suffix
repeat(s, n) Repeat string
slice(s, start, end) Substring
format(tmpl, ...) Format with {}
logos
let s = "  Hello, World!  "

print(upper(s))
print(lower(s))
print(trim(s))

print(replace("banana", "a", "o"))
print(str(contains("hello", "ell")))
print(str(startsWith("hello", "he")))
print(str(endsWith("hello", "lo")))

let words = split("a,b,c,d", ",")
print(join(words, "-"))

print(repeat("ha", 3))
print(slice("hello", 1, 4))
print(format("Name: {}, Age: {}", "Bob", 25))

Type Conversion

str(value) Convert to string (short alias)
int(value) Convert to int (short alias)
float(value) Convert to float (short alias)
toStr(value) Convert to string
toInt(value) Convert to int
toFloat(value) Convert to float
toBool(value) Convert to bool
logos
let n = int("42")
let f = float("3.14")

let s1 = str(42)
let s2 = str(3.14)

let b1 = toBool(true)
let b2 = toBool(false)

print(type(42))
print(type("hello"))
print(type([1,2,3]))

Array Operations

push(arr, val) Add to end
prepend(arr, val) Add to start
pop(arr) Remove last
first(arr) First element
last(arr) Last element
tail(arr) All except first
reverse(arr) Reverse order
sort(arr) Sort array (string or numeric)
contains(arr, val) Check membership
range(start, end, step?) 0 to end (exclusive). Use step=-1 for countdown.
logos
let nums = [1, 2, 3, 4, 5]

nums = push(nums, 6)
nums = prepend(nums, 0)

print(first(nums))
print(last(nums))

let popped = pop(nums)
print(str(popped))

let rest = tail(nums)

let reversed = reverse([1, 2, 3])
let sorted = sort([3, 1, 4, 1, 5])

print(str(contains([1, 2, 3], 2)))

// range() for numeric iteration (v0.4.2)
for i in range(0, 10) {
    print(i)
}

// With step
for i in range(0, 20, 2) {
    print(i)  // 0, 2, 4, 6, ...
}

// Countdown
for i in range(5, 0, -1) {
    print(i)  // 5, 4, 3, 2
}

Table Operations

keys(t) Array of keys
values(t) Array of values
has(t, key) Check if key exists
tableDelete(t, key) Remove key
merge(t1, t2) Merge tables
logos
let user = table{
    name: "Alice",
    age: 30,
    active: true,
}

print(user.name)

print(str(has(user, "email")))

let k = keys(user)
let v = values(user)

let updated = tableDelete(user, "age")

let extra = table{ role: "admin", age: 31 }
let merged = merge(user, extra)

JSON try

parseJson(s) Parse JSON (try)
toJson(value) To JSON string (try)
prettyJson(t) Formatted JSON (try)
logos
// parseJson, toJson, prettyJson return {ok, value, error}
// Use try for clean error handling (v0.4+)

let data = try parseJson("{\"name\": \"Bob\", \"scores\": [95, 87, 92]}")
print(data["name"])
print(str(data["scores"][0]))

let obj = table{ "status": "ok", "count": 42 }
let jsonStr = try toJson(obj)
print(jsonStr)

let parsed = try parseJson("{\"user\": {\"name\": \"Alice\"}}")
print(try prettyJson(parsed))

Math

mathAbs(n) Absolute value
mathPow(a, b) Power (a^b)
mathSqrt(n) Square root
mathFloor(n) Round down
mathCeil(n) Round up
mathRound(n) Round nearest
mathMin(a, b) Minimum
mathMax(a, b) Maximum
mathRandom() Random float 0-1
mathRandomInt(a, b) Random int a-b
mathPi() Pi constant
logos
	print(str(mathAbs(-42)))
print(str(mathPow(2, 10)))
print(str(mathRandomInt(1, 6)))

OS/System

pwd() Current directory
cd(path) Change directory
env(name) Get env var
setenv(n, v) Set env var
args() CLI args (user args at index 0). Not available in compiled binaries.
sleep(ms) Wait milliseconds
osname() "linux"/"darwin"
exit(code?) Exit program (default code 1)
run(cmd, ...) Run command (try)
shell(cmd) Shell command (try)

args() Important

Args are sliced to remove the binary path and script path. User arguments start at index 0:

logos
// Running: lgs script.lgs --name "Alice" --verbose
let cliArgs = args()

print(len(cliArgs))  // 2 (not 4)
print(cliArgs[0])    // "--name"
print(cliArgs[1])    // "Alice"
// Binary and script paths are already removed

// Use with flags
if contains(cliArgs, "--verbose") {
    print("Verbose mode enabled")
}

run() try

logos
// run() - executes a command directly (no shell)
// Use try for clean error handling (v0.4+)

let result = try run("ls", "-la")
print(result)

// With arguments
let gitResult = try run("git", "status")
print(gitResult)

let echoResult = try run("echo", "hello")
print(echoResult)

shell() try

logos
// shell() - executes command through shell (sh -c)
// Use try for clean error handling (v0.4+)

let dateResult = try shell("date")
print(dateResult)

// Shell features work!
let psResult = try shell("ps aux | grep node")
print(psResult)

// Variables
let pathResult = try shell("echo $HOME")
print(pathResult)

// Multiple commands
let multiResult = try shell("echo 'First' && echo 'Second'")
print(multiResult)

Time

timeNow() Unix timestamp (sec)
timeMs() Unix timestamp (ms)
timeStr() "HH:MM:SS"
dateStr() "YYYY-MM-DD"
dateTimeStr() "YYYY-MM-DD HH:MM:SS"
timeFormat(ts, fmt) Custom format
logos
print(str(timeNow()))
print(str(timeMs()))

print(timeStr())
print(dateStr())
print(dateTimeStr())

let ts = timeNow()
print(timeFormat(ts, "January 2, 2006"))
print(timeFormat(ts, "02/01/2006"))

HTTP try + pipe

httpGet(url) GET request (try)
httpGet(url, header) GET with header
httpPost(url, body, header) POST request
httpPut(url, body, header) PUT request
httpPatch(url, body, header) PATCH request
httpDelete(url, header) DELETE request
logos
// HTTP functions return {ok, value: {body, status}, error}
// body is a string, status is an integer HTTP status code

// All HTTP functions accept: (url, body?, headers?)
// body is optional for GET/DELETE; headers always optional

// GET - fetch data
let body = try httpGet("https://api.example.com/users")
print(body)

// GET with headers (authentication, custom headers)
let headers = table{
    "Authorization": "Bearer " + env("API_TOKEN"),
    "Content-Type": "application/json"
}
let data = try httpGet("https://api.example.com/private", headers)

// POST - create resource (url, body, headers?)
let payload = try toJson(table{ name: "Alice", email: "alice@example.com" })
let res = try httpPost("https://api.example.com/users", payload)
print("Created! Status: " + str(res.value.status))

// POST with all three args (url, body, headers)
let authHeaders = table{ "Authorization": "Bearer " + env("API_TOKEN") }
let createRes = try httpPost("https://api.example.com/users", payload, authHeaders)

// Tables are auto-serialized to JSON — no need for toJson() (v0.4.6)
let tablePayload = table{ name: "Alice", email: "alice@example.com" }
let autoRes = try httpPost("https://api.example.com/users", tablePayload)

// PUT - replace resource entirely (url, body, headers?)
let update = try toJson(table{ name: "Alice", id: 1 })
let putRes = try httpPut("https://api.example.com/users/1", update)

// PUT with headers
let putAuth = table{ "Authorization": "Bearer " + env("API_TOKEN") }
let putRes2 = try httpPut("https://api.example.com/users/1", update, putAuth)

// PATCH - partial update (url, body, headers?)
let patch = try toJson(table{ email: "newemail@example.com" })
let patchRes = try httpPatch("https://api.example.com/users/1", patch)

// DELETE - remove resource (url, headers?)
let delRes = try httpDelete("https://api.example.com/users/1")
print("Deleted! Status: " + str(delRes.value.status))

// DELETE with headers
let delAuth = table{ "Authorization": "Bearer " + env("API_TOKEN") }
let delRes2 = try httpDelete("https://api.example.com/users/1", delAuth)

// Handle non-2xx responses (status is included in response)
let res = httpGet("https://api.example.com/not-found")
if !res.ok {
    print("Error: " + res.error)
} else if res.value.status >= 400 {
    print("HTTP error: " + str(res.value.status))
} else {
    print("Success: " + res.value.body)
}

// Pipes - fetch, parse, transform
let users = try httpGet("https://api.example.com/users")
    |> try parseJson
    |> filter(fn(u) -> u.active)
    |> map(fn(u) -> u.name)

Regex v0.4.3

reMatch(pattern, text) True if pattern matches
reFind(pattern, text) First match or null
reFindAll(pattern, text) Array of all matches
reReplace(pattern, text, repl) Replace all matches
reSplit(pattern, text) Split by pattern
reGroups(pattern, text) Capture groups array
logos
// reMatch - returns true/false if pattern matches
print(reMatch(`\d+`, "hello 123"))     // true
print(reMatch(`\d+`, "hello world"))  // false

// reFind - find first match, returns string or null
print(reFind(`\d+`, "there are 3 cats"))    // "3"
print(reFind(`\d+`, "no numbers here"))    // null

// reFindAll - find all matches, returns array
print(reFindAll(`\d+`, "3 cats and 12 dogs"))  // ["3", "12"]

// reReplace - replace all matches
print(reReplace(`\d+`, "I have 3 cats", "X"))  // "I have X cats"

// reSplit - split by pattern
print(reSplit(`\s+`, "split   this   string"))  // ["split", "this", "string"]

// reGroups - extract capture groups
let email = "uthman@gmail.com"
let parts = reGroups(`(\w+)@(\w+)\.(\w+)`, email)
print(parts)  // ["uthman", "gmail", "com"]