Lus

A small, productive programming language designed to be picked up easily by programmers and put to good use right away.

curl -fsSL https://lus.dev/install.sh | sh

Lus at a glance

permissions

Scripts run under deny-by-default permissions. pledge grants capabilities at runtime and can seal the set.

pledge("fs:read=/var/log/*")   -- read access to logs only
pledge("network:http")
pledge("seal")                 -- lock the permission set

local ok = catch fs.list("/home")
-- ok == false: outside the pledged set
queries unstable

An @ expression builds a first-class query with a fixed logical pipeline. It is evaluated each time it is iterated.

local adults =
    @people as p
     where p.age > 18
     select p.name, p.age
     order by p.age desc

for row in query(adults) do
    print(row.name, row.age)
end
sqlite unstable

io.sqlite opens file-backed or in-memory databases. A database table serves as a query source and receives the query as parameterized SQL.

local db <close> = io.sqlite("app.db")

db:run("INSERT INTO users (name, age) VALUES (?, ?)", "Alice", 30)

for u in query(@db.users as u where u.age >= 18 select u.name) do
    print(u.name)
end
concurrency

A worker runs a script in a separate interpreter state on the thread pool and exchanges messages with its parent.

local w = worker.create("crunch.lus", { data = "input" })
worker.send(w, "start")

while result = worker.receive(w) do
    print(result)
end
time unstable

The time library separates absolute instants, civil datetimes, and durations. Named zones resolve from tzdata embedded in the runtime.

local now = time.now()                    -- instant
local later = now + time.hours(72)
local ny = time.zone("America/New_York")

print(later:at(ny):iso())                 -- wall clock in New York
binary data

A vector is a mutable byte buffer. vector.archive reads and writes gzip, zstd, brotli, and lz4.

local v = vector.create(16)
vector.pack(v, 0, "I4I4I4I4", 1, 2, 3, 4)

local packed = vector.archive.zstd.compress(v)
local restored = vector.archive.zstd.decompress(packed)