Website rebuilt from scratch based on analysis of 11 beloved language websites (Elm, Zig, Gleam, Swift, Kotlin, Haskell, OCaml, Crystal, Roc, Rust, Go). New website structure: - Homepage with hero, playground, three pillars, install guide - Language Tour with interactive lessons (hello world, types, effects) - Examples cookbook with categorized sidebar - API documentation index - Installation guide (Nix and source) - Sleek/noble design (black/gold, serif typography) Also includes: - New stdlib/json.lux module for JSON serialization - Enhanced stdlib/http.lux with middleware and routing - New string functions (charAt, indexOf, lastIndexOf, repeat) - LSP improvements (rename, signature help, formatting) - Package manager transitive dependency resolution - Updated documentation for effects and stdlib - New showcase example (task_manager.lux) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
480 lines
12 KiB
Markdown
480 lines
12 KiB
Markdown
# Chapter 9: Standard Library
|
|
|
|
Lux comes with a comprehensive standard library. This chapter covers the built-in modules.
|
|
|
|
## Built-in Functions
|
|
|
|
Always available, no import needed:
|
|
|
|
```lux
|
|
toString(42) // "42" - convert any value to string
|
|
typeOf(42) // "Int" - get type name
|
|
print("hello") // Print to console (shortcut)
|
|
```
|
|
|
|
## List Module
|
|
|
|
Operations on lists:
|
|
|
|
```lux
|
|
let nums = [1, 2, 3, 4, 5]
|
|
|
|
// Transformations
|
|
List.map(nums, fn(x: Int): Int => x * 2) // [2, 4, 6, 8, 10]
|
|
List.filter(nums, fn(x: Int): Bool => x > 2) // [3, 4, 5]
|
|
List.fold(nums, 0, fn(acc: Int, x: Int): Int => acc + x) // 15
|
|
|
|
// Access
|
|
List.head(nums) // Some(1)
|
|
List.tail(nums) // [2, 3, 4, 5]
|
|
List.get(nums, 2) // Some(3)
|
|
List.length(nums) // 5
|
|
List.isEmpty([]) // true
|
|
|
|
// Building
|
|
List.range(1, 5) // [1, 2, 3, 4]
|
|
List.concat([1,2], [3,4]) // [1, 2, 3, 4]
|
|
List.reverse(nums) // [5, 4, 3, 2, 1]
|
|
|
|
// Searching
|
|
List.find(nums, fn(x: Int): Bool => x > 3) // Some(4)
|
|
List.any(nums, fn(x: Int): Bool => x > 3) // true
|
|
List.all(nums, fn(x: Int): Bool => x > 0) // true
|
|
|
|
// Slicing
|
|
List.take(nums, 3) // [1, 2, 3]
|
|
List.drop(nums, 3) // [4, 5]
|
|
```
|
|
|
|
## String Module
|
|
|
|
String manipulation:
|
|
|
|
```lux
|
|
let s = "Hello, World!"
|
|
|
|
// Info
|
|
String.length(s) // 13
|
|
String.isEmpty("") // true
|
|
|
|
// Search
|
|
String.contains(s, "World") // true
|
|
String.startsWith(s, "Hello") // true
|
|
String.endsWith(s, "!") // true
|
|
|
|
// Transform
|
|
String.toUpper(s) // "HELLO, WORLD!"
|
|
String.toLower(s) // "hello, world!"
|
|
String.trim(" hi ") // "hi"
|
|
String.replace(s, "World", "Lux") // "Hello, Lux!"
|
|
|
|
// Split/Join
|
|
String.split("a,b,c", ",") // ["a", "b", "c"]
|
|
String.join(["a","b","c"], "-") // "a-b-c"
|
|
String.lines("a\nb\nc") // ["a", "b", "c"]
|
|
String.chars("abc") // ["a", "b", "c"]
|
|
|
|
// Substring
|
|
String.substring(s, 0, 5) // "Hello"
|
|
```
|
|
|
|
## Option Module
|
|
|
|
Working with optional values:
|
|
|
|
```lux
|
|
let some = Some(42)
|
|
let none: Option<Int> = None
|
|
|
|
// Check
|
|
Option.isSome(some) // true
|
|
Option.isNone(none) // true
|
|
|
|
// Transform
|
|
Option.map(some, fn(x: Int): Int => x * 2) // Some(84)
|
|
Option.flatMap(some, fn(x: Int): Option<Int> => Some(x + 1)) // Some(43)
|
|
|
|
// Extract
|
|
Option.getOrElse(some, 0) // 42
|
|
Option.getOrElse(none, 0) // 0
|
|
```
|
|
|
|
## Result Module
|
|
|
|
Working with results:
|
|
|
|
```lux
|
|
let ok: Result<Int, String> = Ok(42)
|
|
let err: Result<Int, String> = Err("oops")
|
|
|
|
// Check
|
|
Result.isOk(ok) // true
|
|
Result.isErr(err) // true
|
|
|
|
// Transform
|
|
Result.map(ok, fn(x: Int): Int => x * 2) // Ok(84)
|
|
Result.mapErr(err, fn(e: String): String => "Error: " + e) // Err("Error: oops")
|
|
Result.flatMap(ok, fn(x: Int): Result<Int, String> => Ok(x + 1)) // Ok(43)
|
|
|
|
// Extract
|
|
Result.getOrElse(ok, 0) // 42
|
|
Result.getOrElse(err, 0) // 0
|
|
```
|
|
|
|
## Math Module
|
|
|
|
Mathematical functions:
|
|
|
|
```lux
|
|
Math.abs(-5) // 5
|
|
Math.min(3, 7) // 3
|
|
Math.max(3, 7) // 7
|
|
Math.pow(2, 10) // 1024
|
|
Math.sqrt(16) // 4.0
|
|
Math.floor(3.7) // 3
|
|
Math.ceil(3.2) // 4
|
|
Math.round(3.5) // 4
|
|
```
|
|
|
|
## Json Module
|
|
|
|
JSON parsing and generation:
|
|
|
|
```lux
|
|
// Parse JSON string
|
|
let data = Json.parse("{\"name\": \"Alice\", \"age\": 30}")
|
|
|
|
// Access fields
|
|
Json.get(data, "name") // Some("Alice")
|
|
Json.getInt(data, "age") // Some(30)
|
|
|
|
// Create JSON
|
|
let obj = Json.object([
|
|
("name", Json.string("Bob")),
|
|
("age", Json.int(25))
|
|
])
|
|
|
|
// Convert to string
|
|
Json.stringify(obj) // "{\"name\":\"Bob\",\"age\":25}"
|
|
Json.prettyPrint(obj) // Formatted with indentation
|
|
```
|
|
|
|
## Standard Library Modules (std/)
|
|
|
|
Import from the `std/` directory:
|
|
|
|
### std/prelude
|
|
|
|
```lux
|
|
import std/prelude.*
|
|
|
|
identity(42) // 42
|
|
compose(f, g) // Function composition
|
|
flip(f) // Flip argument order
|
|
not(true) // false
|
|
and(true, false) // false
|
|
or(true, false) // true
|
|
```
|
|
|
|
### std/io
|
|
|
|
```lux
|
|
import std/io
|
|
|
|
io.println("Hello") // Print with newline
|
|
io.print("No newline") // Print without newline
|
|
io.readLine() // Read line from input
|
|
io.debug("label", value) // Debug print, returns value
|
|
```
|
|
|
|
### std/option
|
|
|
|
```lux
|
|
import std/option as opt
|
|
|
|
opt.some(42) // Some(42)
|
|
opt.none() // None
|
|
opt.map(x, f) // Map function over option
|
|
opt.flatMap(x, f) // FlatMap
|
|
opt.filter(x, pred) // Filter by predicate
|
|
opt.toList(x) // Convert to list
|
|
```
|
|
|
|
### std/result
|
|
|
|
```lux
|
|
import std/result as res
|
|
|
|
res.ok(42) // Ok(42)
|
|
res.err("oops") // Err("oops")
|
|
res.mapOk(r, f) // Map over Ok value
|
|
res.mapErr(r, f) // Map over Err value
|
|
res.unwrapOr(r, default) // Get value or default
|
|
```
|
|
|
|
## Built-in Effects
|
|
|
|
### Console
|
|
|
|
```lux
|
|
fn example(): Unit with {Console} = {
|
|
Console.print("Hello") // Print string
|
|
let line = Console.readLine() // Read line
|
|
let num = Console.readInt() // Read integer
|
|
}
|
|
```
|
|
|
|
### File
|
|
|
|
```lux
|
|
fn example(): Unit with {File} = {
|
|
let content = File.read("file.txt") // Read file
|
|
File.write("out.txt", "content") // Write file
|
|
let exists = File.exists("file.txt") // Check existence
|
|
let files = File.list("./dir") // List directory
|
|
File.mkdir("newdir") // Create directory
|
|
File.delete("file.txt") // Delete file
|
|
}
|
|
```
|
|
|
|
### Process
|
|
|
|
```lux
|
|
fn example(): Unit with {Process} = {
|
|
let output = Process.exec("ls", ["-la"]) // Run command
|
|
let home = Process.env("HOME") // Get env var
|
|
let args = Process.args() // Get CLI args
|
|
let cwd = Process.cwd() // Current directory
|
|
Process.exit(0) // Exit program
|
|
}
|
|
```
|
|
|
|
### Http
|
|
|
|
```lux
|
|
fn example(): Unit with {Http} = {
|
|
let body = Http.get("https://api.example.com/data")
|
|
let response = Http.post("https://api.example.com/data", jsonBody)
|
|
Http.put("https://api.example.com/data/1", updatedBody)
|
|
Http.delete("https://api.example.com/data/1")
|
|
}
|
|
```
|
|
|
|
### HttpServer
|
|
|
|
```lux
|
|
fn example(): Unit with {HttpServer, Console} = {
|
|
HttpServer.listen(8080) // Start server on port
|
|
Console.print("Server listening on port 8080")
|
|
|
|
let req = HttpServer.accept() // Wait for request
|
|
// req is { method: String, path: String, body: String, headers: List<(String, String)> }
|
|
|
|
Console.print("Got " + req.method + " " + req.path)
|
|
HttpServer.respond(200, "Hello, World!") // Send response
|
|
|
|
HttpServer.stop() // Stop server
|
|
}
|
|
```
|
|
|
|
### Time
|
|
|
|
```lux
|
|
fn example(): Unit with {Time, Console} = {
|
|
let start = Time.now() // Current timestamp (milliseconds)
|
|
Time.sleep(1000) // Sleep for 1 second
|
|
let elapsed = Time.now() - start
|
|
Console.print("Elapsed: " + toString(elapsed) + "ms")
|
|
}
|
|
```
|
|
|
|
### Random
|
|
|
|
```lux
|
|
fn example(): Unit with {Random} = {
|
|
let n = Random.int(1, 100) // Random int in range
|
|
let f = Random.float() // Random float 0.0-1.0
|
|
let b = Random.bool() // Random boolean
|
|
}
|
|
```
|
|
|
|
### State
|
|
|
|
```lux
|
|
fn example(): Int with {State} = {
|
|
let current = State.get() // Get current state
|
|
State.put(current + 1) // Update state
|
|
State.get()
|
|
}
|
|
|
|
// Initialize with value
|
|
run example() with { State = 0 }
|
|
```
|
|
|
|
### Fail
|
|
|
|
```lux
|
|
fn example(): Int with {Fail} = {
|
|
if condition then Fail.fail("Error message")
|
|
else 42
|
|
}
|
|
```
|
|
|
|
### Sql (SQLite)
|
|
|
|
```lux
|
|
fn example(): Unit with {Sql, Console} = {
|
|
let conn = Sql.open("mydb.sqlite") // Open database file
|
|
// Or: let conn = Sql.openMemory() // In-memory database
|
|
|
|
// Execute statements (returns row count)
|
|
Sql.execute(conn, "CREATE TABLE users (id INTEGER, name TEXT)")
|
|
Sql.execute(conn, "INSERT INTO users VALUES (1, 'Alice')")
|
|
|
|
// Query returns list of rows
|
|
let rows = Sql.query(conn, "SELECT * FROM users")
|
|
|
|
// Query for single row
|
|
let user = Sql.queryOne(conn, "SELECT * FROM users WHERE id = 1")
|
|
|
|
// Transactions
|
|
Sql.beginTx(conn)
|
|
Sql.execute(conn, "UPDATE users SET name = 'Bob' WHERE id = 1")
|
|
Sql.commit(conn) // Or: Sql.rollback(conn)
|
|
|
|
Sql.close(conn)
|
|
}
|
|
```
|
|
|
|
### Postgres (PostgreSQL)
|
|
|
|
```lux
|
|
fn example(): Unit with {Postgres, Console} = {
|
|
let conn = Postgres.connect("postgres://user:pass@localhost/mydb")
|
|
|
|
// Execute statements
|
|
Postgres.execute(conn, "INSERT INTO users (name) VALUES ('Alice')")
|
|
|
|
// Query returns list of rows
|
|
let rows = Postgres.query(conn, "SELECT * FROM users")
|
|
|
|
// Query for single row
|
|
let user = Postgres.queryOne(conn, "SELECT * FROM users WHERE id = 1")
|
|
|
|
Postgres.close(conn)
|
|
}
|
|
```
|
|
|
|
### Concurrent (Parallel Tasks)
|
|
|
|
```lux
|
|
fn example(): Unit with {Concurrent, Console} = {
|
|
// Spawn concurrent tasks
|
|
let task1 = Concurrent.spawn(fn(): Int => expensiveComputation(1))
|
|
let task2 = Concurrent.spawn(fn(): Int => expensiveComputation(2))
|
|
|
|
// Do other work while tasks run
|
|
Console.print("Tasks spawned, doing other work...")
|
|
|
|
// Wait for tasks to complete
|
|
let result1 = Concurrent.await(task1)
|
|
let result2 = Concurrent.await(task2)
|
|
|
|
Console.print("Results: " + toString(result1) + ", " + toString(result2))
|
|
|
|
// Check task status
|
|
if Concurrent.isRunning(task1) then
|
|
Concurrent.cancel(task1)
|
|
|
|
// Non-blocking sleep
|
|
Concurrent.sleep(100) // 100ms
|
|
|
|
// Yield to allow other tasks to run
|
|
Concurrent.yield()
|
|
|
|
// Get active task count
|
|
let count = Concurrent.taskCount()
|
|
}
|
|
```
|
|
|
|
### Channel (Inter-Task Communication)
|
|
|
|
```lux
|
|
fn example(): Unit with {Concurrent, Channel, Console} = {
|
|
// Create a channel for communication
|
|
let ch = Channel.create()
|
|
|
|
// Spawn producer task
|
|
let producer = Concurrent.spawn(fn(): Unit => {
|
|
Channel.send(ch, 1)
|
|
Channel.send(ch, 2)
|
|
Channel.send(ch, 3)
|
|
Channel.close(ch)
|
|
})
|
|
|
|
// Consumer receives values
|
|
match Channel.receive(ch) {
|
|
Some(value) => Console.print("Received: " + toString(value)),
|
|
None => Console.print("Channel closed")
|
|
}
|
|
|
|
// Non-blocking receive
|
|
match Channel.tryReceive(ch) {
|
|
Some(value) => Console.print("Got: " + toString(value)),
|
|
None => Console.print("No value available")
|
|
}
|
|
|
|
Concurrent.await(producer)
|
|
}
|
|
```
|
|
|
|
### Test
|
|
|
|
Native testing framework:
|
|
|
|
```lux
|
|
fn runTests(): Unit with {Test, Console} = {
|
|
Test.assert(1 + 1 == 2, "basic math")
|
|
Test.assertEqual(List.length([1,2,3]), 3, "list length")
|
|
Test.assertTrue(String.contains("hello", "ell"), "contains check")
|
|
Test.assertFalse(List.isEmpty([1]), "non-empty list")
|
|
}
|
|
|
|
// Run with test handler
|
|
fn main(): Unit with {Console} = {
|
|
run runTests() with { Test = testReporter }
|
|
}
|
|
```
|
|
|
|
## Quick Reference
|
|
|
|
| Module | Key Functions |
|
|
|--------|---------------|
|
|
| List | map, filter, fold, head, tail, length, concat |
|
|
| String | split, join, trim, contains, replace, toUpper |
|
|
| Option | map, flatMap, getOrElse, isSome, isNone |
|
|
| Result | map, mapErr, flatMap, getOrElse, isOk |
|
|
| Math | abs, min, max, pow, sqrt, floor, ceil |
|
|
| Json | parse, stringify, get, object, array |
|
|
|
|
| Effect | Operations |
|
|
|--------|------------|
|
|
| Console | print, readLine, readInt |
|
|
| File | read, write, exists, list, mkdir, delete |
|
|
| Process | exec, env, args, cwd, exit |
|
|
| Http | get, post, put, delete |
|
|
| HttpServer | listen, accept, respond, stop |
|
|
| Time | now, sleep |
|
|
| Random | int, float, bool |
|
|
| State | get, put |
|
|
| Fail | fail |
|
|
| Sql | open, openMemory, close, execute, query, queryOne, beginTx, commit, rollback |
|
|
| Postgres | connect, close, execute, query, queryOne |
|
|
| Concurrent | spawn, await, yield, sleep, cancel, isRunning, taskCount |
|
|
| Channel | create, send, receive, tryReceive, close |
|
|
| Test | assert, assertEqual, assertTrue, assertFalse |
|
|
|
|
## Next
|
|
|
|
[Chapter 10: Advanced Topics](10-advanced.md) - Traits, generics, and optimization.
|