Karl logo karl docs / std

Standard Library Reference

Canonical built-in reference aligned with interpreter/builtins_*.go. Karl is expression-based, functions-first, and concurrency-native. Streams/processes are major features, but part of a broader language model.

1. Language Model

These are language forms (not regular built-ins):

2. Runtime Availability

FeatureCLI / NativeBench / WASM
Core language + collections + strings + mathYesYes
Tasks/channels + stream algebra on in-memory/channel/http sourcesYesYes
Filesystem (readFile, writeFile, read, writer, ...)YesNo
Process API (proc, run, exec sink)YesNo
SQL + signals + httpServeYesNo

3. Prebound Constants

NameValueUsed for
PIPE"pipe"Process stdio mode
INHERIT"inherit"Process stdio mode
NULL"null"Process stdio mode
TEXT"text"Stream mode
BYTES"bytes"Stream mode

4. Core Runtime

NameSignatureReturnNotes
loglog(...values)()Print inspected values.
logtlogt(...values)()Prefixes RFC3339 UTC timestamp.
strstr(value)StringValue stringification.
sleepsleep(ms)()Cooperative delay in milliseconds.
failfail([message])recoverable errorRecover with ? { ... }.
exitexit([message])neverTerminates execution.

5. Concurrency Helpers (Built-ins)

NameSignatureReturnNotes
channelchannel()ChannelAlias of rendezvous().
rendezvousrendezvous()ChannelUnbuffered channel.
bufferedbuffered(size)ChannelBuffered channel.
sendsend(ch, value) or send(ch)() or stream sinksend(ch) drains stream into channel.
recvrecv(ch)[value|null, doneBool]Also ch.recv().
donedone(ch)()Also ch.done().
thenthen(task, fn)TaskAlso task.then(fn).

6. Program Runtime

NameSignatureReturnNotes
argvargv()Array<String>Arguments after -- with karl run.
programPathprogramPath()String|nullCurrent script path.
environenviron()Array<String>KEY=value entries.
envenv(name)String|nullSingle lookup.
readLinereadLine()String|nullReads one line from stdin.

7. Collections

Karl has four collection families: Array, Map, Set, ordered tree, and hierarchical ntree.

7.1 Constructors and Core Shapes

NameSignatureReturnNotes
mapmap() or map(array, fn) or map(fn)Map / Array / stream stageOverloaded constructor + transform + stage.
setset(), set(array), set(map,key,value)Set / MapOverloaded constructor + map update.
treetree(kind?)Treekind is "avl" or "treap".
ntreentree(rootId, rootValue?)NTreeHierarchical tree with stable node IDs.
lenlen(string|bytes|array|map|set|object)IntFor sets, use .size property if preferred.

7.2 Map and Set Operations

NameSignatureReturnNotes
getget(map, key)Value|nullMap lookup only.
addadd(set, value)SetMutates set.
hashas(mapOrSet, key)Bool-
deletedelete(mapOrSet, key)Bool-
keyskeys(mapOrObject)Array-
valuesvalues(mapOrSet)Array-

7.3 Ordered Tree: tree(kind?)

Ordered key-value index (sorted by key). Key domain is homogeneous: int, float, string, or char.

MethodSignatureReturn
sett.set(key, value)Tree
gett.get(key)Value|null
hast.has(key)Bool
deletet.delete(key)Bool
kindt.kind()String
min/maxt.min(), t.max(){ key, value } | null
lower/upper boundt.lowerBound(key), t.upperBound(key){ key, value } | null
floor/ceilt.floor(key), t.ceil(key){ key, value } | null
predecessor/successort.predecessor(key), t.successor(key){ key, value } | null
closestt.closest(key, opts?){ key, value, exact } | null
kClosestt.kClosest(key, k, opts?)[{ key, value, exact, distance }]
rank/selectt.rank(key), t.select(rank)Int|null, { key, value } | null
ranget.range(from, to, opts?)[{ key, value }]
patht.path(key)[{ key, value }] | null
popMin/popMaxt.popMin(), t.popMax(){ key, value } | null
bulkLoadt.bulkLoad(items, opts?)Tree
validatet.validate(){ ok, reason }
keys/values/itemst.keys(), t.values(), t.items()Array
metricst.size, t.maxDepth(), t.maxWidth()Int
let prices = tree("avl")
let seeds = [18, 22, 27, 35, 44, 56, 63, 71, 89]
seeds.forEach(p ->
    prices.set(p, { sku: "p-" + str(p), price: p, })
)
log("floor50:", prices.floor(50))
log("ceil50:", prices.ceil(50))
log("nearest42:", prices.kClosest(42, 3))
log("median:", prices.select(4))
log("rank35:", prices.rank(35))
log("valid:", prices.validate())

7.4 Hierarchical Tree: ntree(rootId, rootValue?)

Explicit parent/children hierarchy for topology navigation.

MethodSignatureReturn
get/sett.get(id), t.set(id, value)node|null, Bool
append/prepend/insertAtt.append(parent, child, value), ...NTree
removet.remove(id, opts?)Bool
movet.move(id, newParent, opts?)NTree
parent/children/siblingst.parent(id), t.children(id), t.siblings(id, opts?)node|null, [node], [node]
ancestors/descendantst.ancestors(id), t.descendants(id, opts?)[node]
depth/heightt.depth(id), t.height(id)Int|null
lca/pathBetweent.lca(a, b), t.pathBetween(a, b)node|null, [node]|null
subtreeSizet.subtreeSize(id)Int|null
patht.path(id)[node]|null
find/findAll/roott.find(fn), t.findAll(fn), t.root()node|null, [node], node
sizet.sizeInt
let topo = ntree("root", { label: "Root", })
topo.append("root", "api", { label: "API", })
topo.append("root", "worker", { label: "Worker", })
topo.append("api", "http", { label: "HTTP", })
topo.append("worker", "jobs", { label: "Jobs", })

log({
    depthJobs: topo.depth("jobs"),
    lca: topo.lca("http", "jobs"),
    path: topo.pathBetween("http", "jobs").map(n -> n.id),
})

8. Sequence Operators

These are overloaded between arrays and streams (where noted).

NameSignatureReturn
filterfilter(array, pred) or filter(pred)Array / stream stage
flatMapflatMap(array, fn) or flatMap(fn)Array / stream stage
reducereduce(array, fn, init) or reduce(init, fn)Value / stream sink
forEachforEach(array, fn) or forEach(fn)Unit / stream sink
sortsort(array, cmp) or sort()/sort(cmp)Array / stream stage
findfind(array, pred)Value|null
sumsum(array)Int|Float
taketake(n)stream stage
dropdrop(n)stream stage
chunkchunk(size)stream stage
windowwindow(size, step)stream stage
throttlethrottle(ms)stream stage
debouncedebounce(ms)stream stage
distinctdistinct()stream stage
countcount()stream sink Int
group_countgroup_count([keyFn])stream sink Map
reduce_by_keyreduce_by_key(keyFn, init, reducerFn)stream sink Map
toptop(n[, scoreFn])stream sink Array
partitionpartition(array, pred) or partition(selector[, keys])Array pair / branch object
splitsplit(pred) (stream) or split(text, sep) (string)Object / Array<String>

9. Strings

NameSignatureReturn
trimtrim(text)String
toLowertoLower(text)String
toUppertoUpper(text)String
splitsplit(text, sep)Array<String>
charschars(text)Array<Char>
containscontains(text, sub)Bool
startsWithstartsWith(text, prefix)Bool
endsWithendsWith(text, suffix)Bool
replacereplace(text, old, new)String

10. Encoding + Data

NameSignatureReturnNotes
fromJsonfromJson(text) or fromJson()Value / stream stageRecoverable parse failures.
toJsontoJson(value) or toJson()String / stream stageEncoding fails on unsupported values.
fromUtf8fromUtf8(bytes) or fromUtf8()String / stream stageRecoverable on invalid UTF-8.
toUtf8toUtf8(text) or toUtf8()Bytes / stream stage-
bytesJoinbytesJoin(arrayOfBytes)BytesConcatenates byte chunks.
parseIntparseInt(text)IntRuntime error on invalid input.

11. Time / UUID / Crypto

NameSignatureReturn
nownow()Int (ms epoch)
timeParseRFC3339timeParseRFC3339(text)Int
timeFormatRFC3339timeFormatRFC3339(ms)String
timeAddtimeAdd(ms, deltaMs)Int
timeDifftimeDiff(aMs, bMs)Int
sha256sha256(text)String (hex)
uuidNewuuidNew()String
uuidParseuuidParse(text)String
uuidValiduuidValid(text)Bool

12. Math + Random

NameSignatureReturn
randrand()Int
randIntrandInt(min, max)Int
randFloatrandFloat(min, max)Float
absabs(number)Int|Float
sqrtsqrt(number)Float
powpow(base, exp)Float
sinsin(number)Float
coscos(number)Float
tantan(number)Float
floorfloor(number)Int
ceilceil(number)Int
minmin(a, b)Int|Float
maxmax(a, b)Int|Float
clampclamp(v, min, max)Int|Float

13. Filesystem

NameSignatureReturnNotes
readFilereadFile(path)StringWhole-file read as text.
writeFilewriteFile(path, text)()Overwrite.
appendFileappendFile(path, text)()Append.
deleteFiledeleteFile(path)()-
existsexists(path)Bool-
listDirlistDir(path)Array<String>-
readerreader(path, opts?)<stream-reader>Low-level stream handle.
writerwriter(path, opts?)<stream-writer>Low-level stream handle.
readread(path, opts?)<stream-source>Preferred pipeline source.
writewrite(path, opts?)<stream-sink>Preferred pipeline sink.

14. HTTP

NameSignatureReturnNotes
httphttp(url, opts?)<stream-source>Preferred HTTP form.
httpServehttpServe({ addr, routes })ServerNative runtime only.
httpServerStophttpServerStop(server)()Graceful stop.

15. SQL

NameSignatureReturn
sqlOpensqlOpen(dsn)Db
sqlClosesqlClose(db)()
sqlExecsqlExec(connOrTx, query, paramsArray){ rowsAffected }
sqlQuerysqlQuery(connOrTx, query, paramsArray)Array<Object>
sqlQueryOnesqlQueryOne(connOrTx, query, paramsArray)Object|null
sqlBeginsqlBegin(db)Tx
sqlCommitsqlCommit(tx)()
sqlRollbacksqlRollback(tx)()

16. Signals

NameSignatureReturn
signalWatchsignalWatch(["SIGINT", ...])Channel<String>

17. Process API

NameSignatureReturnNotes
procproc(spec, opts?) or proc(command, ...args, opts?)<process>Starts immediately.
runrun(spec, opts?) or run(command, ...args, opts?)RunStatusBlocking convenience form.

Process members:

p.pid
p.running
p.stdin   // available when stdin: PIPE
p.stdout  // available when stdout: PIPE
p.stderr  // available when stderr: PIPE
p.abort()
p.kill()
p.signal("SIGTERM")

Status objects:

wait p -> { ok, code, signal, timedOut, aborted, durationMs, }
run(...) -> { ok, code, signal, timedOut, aborted, durationMs, output, error, outputTruncated, errorTruncated, }

18. Stream API

18.1 Sources

read(path, opts?)
stdin(opts?)
http(url, opts?)
fromChannel(ch)
merge(a, b, ...) or merge([a, b, ...])
zip(a, b)
join(left, right, leftKeyFn, rightKeyFn)

18.2 Stages

lines()
fromJson()
toJson()
fromUtf8()
toUtf8()
map(fn)
filter(fn)
flatMap(fn)
distinct()
sort([cmp])
take(n)
drop(n)
chunk(size)
window(size, step)
throttle(ms)
debounce(ms)
tee(sink)
spill(path, opts?)

18.3 Sinks

stdout()
write(path, opts?)
collect()
toChannel(ch)
send(ch)
reduce(init, fn)
forEach(fn)
count()
group_count([keyFn])
reduce_by_key(keyFn, init, reducerFn)
top(n[, scoreFn])
partition(selector[, branchKeys])
split(pred)
exec(specOrCommand...)

18.4 Stream Handle Members

// source or plan
s.read()      // [item, eof]
s.close()

// reader
r.read([size]) // [chunk, eof]
r.close()

// writer
w.write(chunk) // bytes written
w.close()

19. Method Sugar

TypePropertiesMethods
Array.length.map .filter .reduce .forEach .sum .find .sort .push
String.length.split .chars .trim .toLower .toUpper .contains .startsWith .endsWith .replace
Bytes.length-
Map-.get .set .has .delete .keys .values
Set.size.add .has .delete .values
Tree.size.set .get .has .delete .kind .min .max .maxDepth .maxWidth .lowerBound .upperBound .floor .ceil .predecessor .successor .closest .kClosest .rank .select .range .path .popMin .popMax .bulkLoad .validate .keys .values .items
NTree.size.get .set .append .prepend .insertAt .remove .move .parent .children .siblings .ancestors .descendants .depth .height .lca .pathBetween .subtreeSize .path .find .findAll .root
Channel-.send .recv .done
Task-.then .cancel
Process.pid .running .stdin .stdout .stderr.abort .kill .signal
Stream source/plan-.read .close
Stream reader-.read .close
Stream writer-.write .close

20. Non-Obvious Examples

Overloaded map: constructor, array transform, stream stage

let m = map()
let xs = map([1, 2, 3], x -> x * 2)
let ys = read("items.txt", { type: TEXT, }) | lines() | map(_ + "!") | collect()

partition(selector, keys): branch into named streams

let branches = read("events.ndjson", { type: TEXT, })
    | lines()
    | filter(_ != "")
    | fromJson()
    | partition(e -> e.level, ["ERROR", "WARN", "INFO"])

let errors = branches.ERROR | count()
let warns = branches.WARN | count()
log({ errors, warns, })

join(left, right, leftKeyFn, rightKeyFn)

let users = read("users.ndjson", { type: TEXT, }) | lines() | filter(_ != "") | fromJson()
let orders = read("orders.ndjson", { type: TEXT, }) | lines() | filter(_ != "") | fromJson()

let joined = join(users, orders, u -> u.id, o -> o.user_id) | collect()

run vs proc

let st = run("kubectl", "get", "ns") // blocking capture

let p = proc("kubectl", "logs", "-f", "deploy/api", { stdout: PIPE, stderr: NULL, stdoutType: TEXT, })
let [line, eof] = p.stdout.read()
let final = wait p

HTTP stream + JSON stage

let byTeam = http("https://example.com/events.ndjson", { type: TEXT, })
    | lines()
    | filter(_ != "")
    | fromJson()
    | group_count(_.team)

exec sink: pipe stream output into external command

let st = read("app.log", { type: TEXT, })
    | lines()
    | filter(_.contains("ERROR"))
    | exec("wc", "-l", { maxOutputBytes: 1024, })

log(st.output.trim())

stream cursor semantics

let s = read("events.log", { type: TEXT, }) | lines()
let [a, eofA] = s.read()
let [b, eofB] = s.read()
s.close()
let [c, eofC] = s.read() // [null, true]

21. Compatibility Notes