Library
It ships inside kon.exe and is written in Kon, with small C bridges for operating system calls. It fills the gap until Kon has its full standard library.
Using it
import "std/text.kon" as text
import "std/json.kon" as json
func main(): i32 {
let source = text.of("[1, 2, 3]")
let doc = json.parse(source)
print(doc.count(doc.root()))
return 0
}There are no files to copy and no flags to add. The reference lists every function.
std/text
Text is UTF-8, and positions count bytes.
| Name | What it does |
|---|---|
fromInt, fromUint | Whole number to text |
fromFloat(value, decimals) | Fixed decimals, up to 9, or none if it cannot be shown |
fromFloatShortest | The shortest text that reads back as exactly this float |
parseInt, parseUint, parseFloat | Text to number, or none. Limits are checked, and floats round correctly |
find, findFrom, contains | Search |
startsWith, endsWith, equal, isText, compare | Compare |
split, lines, join, trim, replace, substring | Take apart and put together |
toLowerAscii, toUpperAscii | A to Z only; other letters stay as they are |
readFile, writeFile, appendFile | Whole text files. A write appears complete or not at all |
argument, listDirectory, isDirectoryAt | Program arguments and folder listings as text |
import "std/text.kon" as text
func main(): i32 {
let row = text.of("An, 8.5 ,Hà Nội")
let comma = text.of(",")
let cells = text.split(row, comma)
let score = text.trim(cells[1])
let value = text.parseFloat(score)
match value {
some(number) => { print(number * 2.0) }
none => { return 1 }
}
print(cells[2])
return 0
}std/json
Reads strictly by RFC 8259, and agreed with JavaScript's JSON.parse on 3,000 random documents and their damaged copies. Asking about something absent gives your fallback, however deep the chain.
| Name | What it does |
|---|---|
parse, load | From text or a file. isValid and errorText say what went wrong and on which line |
root, get, getAt, item, first, next, keyOf, count | Find values |
numberOr, intOr, boolOr, textOr | Read a value, or your fallback |
isNull, isBool, isNumber, isText, isArray, isObject, exists | Ask what it is |
document, newObject, newArray, newNumber, newText, newBool, newNull | Make values |
set, setAt, push, setRoot | Put them together |
toText(pretty), save(path) | Write it out |
import "std/json.kon" as json
func main(): i32 {
var doc = json.document()
let root = doc.newObject()
doc.setRoot(root)
let hp = doc.newNumber(100.0)
let added = doc.set(root, "hp", hp)
if !doc.save("save.json") { return 1 }
let back = json.load("save.json")
print(back.numberOr(back.get(back.root(), "hp"), 0.0))
print(back.numberOr(back.get(back.root(), "mana"), 5.0))
return 0
}std/net
TCP, UDP, host lookup, timeouts, and a server for line-based protocols that handles many clients in one thread. There is no HTTP or TLS yet, so it cannot reach most of the web on its own.
| Name | What it does |
|---|---|
connect, connectWithin, listen, accept | TCP connections, with timeouts |
readLine, read, readToEnd, writeLine, writeText, writeAll | Sending and receiving |
bindUdp, sendTo, receive | UDP datagrams |
resolve | The addresses of a host name |
setTimeout, setNonBlocking, waitReadable | Not getting stuck |
serve, poll, sendLine, broadcast, disconnect | A server for many clients |
lastError | Why the last call failed, in a sentence |
import "std/net.kon" as net
import "std/text.kon" as text
// One program on both ends, over this machine's loopback.
func main(): i32 {
let opened = net.listen("127.0.0.1", 0)
match take opened {
some(found) => {
var listener = take found
let address = listener.localAddress()
match take address {
some(place) => {
let attempt = net.connect("127.0.0.1", place.port)
match take attempt {
some(client) => {
var stream = take client
let incoming = listener.accept()
match take incoming {
some(other) => {
var peer = take other
let line = text.of("xin chào")
if !stream.writeLine(line) { return 1 }
let got = peer.readLine()
match take got {
some(value) => { print(value) }
none => { return 2 }
}
}
none => { return 3 }
}
}
none => { return 4 }
}
}
none => { return 5 }
}
}
none => { return 6 }
}
return 0
}A whole chat server:
import "std/net.kon" as net
// A chat server: every line from one client goes to all the others.
func main(): i32 {
let started = net.serve("127.0.0.1", 9000)
match take started {
some(found) => {
var server = take found
while true {
let events = server.poll(1000)
var at: u64 = 0
while at < events.length {
if events[at].isLine() {
let line = events[at].lineText()
let count = server.broadcast(line, events[at].clientId())
}
at += 1
}
}
}
none => {
let why = net.lastError()
print(why)
return 1
}
}
return 0
}
Close a socket with close when you are done. Kon has no destructors yet, so one that is dropped stays open until the program ends.
std/hash
SHA-256, to tell whether content has changed.
| Name | What it does |
|---|---|
sha256, sha256Text | The hash as 64 hex digits |
std/sys
Files as bytes, clocks and arguments. Most programs want std/text on top of it.
| Name | What it does |
|---|---|
readFile, writeFile, appendFile, removeFile, exists | Files as List<u8>, with atomic writes |
makeDirectory, isDirectory, listDirectory, removeDirectoryAt | Folders |
monotonicMillis, unixMillis, sleepMillis | Time |
argumentCount, argument | Program arguments |
std/path
| Name | What it does |
|---|---|
join, baseName, stem, extension, parent, isAbsolute | Paths as text. Both / and \ work on Windows |
walk(folder) | Every file under a folder, in sorted order |
std/args
--name is a flag and --name=value carries a value. A value always needs the =, so a flag can never swallow the word after it.
| Name | What it does |
|---|---|
read, parse | Read the command line |
has, valueOr, positional, count | Ask about it |
std/process
Runs another program without a shell, so spaces and symbols in an argument reach it as they are, and text from outside cannot turn into extra commands.
| Name | What it does |
|---|---|
command(program) | A list with the program first; add arguments to it |
run, runKept | Run and wait. runKept keeps its output and errors together |
didStart, succeeded, exitCode, outputText, outputBytes | What happened |
Data structures
| Name | What it does |
|---|---|
map | Map<K, V>, generic, with your own hash and equality |
intmap | IntMap, a fast table from i64 to i64 |
intset | IntSet |
deque | IntDeque, a queue with both ends |
heap | MinHeap, a priority queue |
grid | Grid, a 2D map with shortest paths |
sort | sortI64, O(n log n) in the worst case |
Numbers
| Name | What it does |
|---|---|
math | min, max, clamp, abs, gcd, integer square root, powers, sine and cosine in degrees |
fixed | Fractions without floats |
random | A repeatable generator. Not for security |
Graphics and sound
std/gfx opens a window, draws to a software canvas and reads the keyboard and mouse. std/audio is a synthesizer written in Kon, and std/kit adds helpers for games. They have been used to test the language on small games: a falling-sand toy, an arcade game, a platformer and a 3D block world at about 155 frames per second, all drawn in software. Windows only for now.
Limits
- Most data structures hold integers.
mapis the one generic so far. - Bytes cross into C one at a time, so very large files are slower than they need to be. This goes away when Kon can pass pointers to C.
- A literal cannot yet stand in for a
String, so needles are writtentext.of(","). - A temporary value cannot be passed where a
viewis expected, so bind it to a name first. sinDegreesis an approximation, accurate to about 0.2%.