Why silt
silt is a statically-typed, expression-based language for building concurrent backend services and tools. It aims for the productivity of a high-level scripting language with the correctness guarantees of an ML-family type system, and it picks a small set of language features carefully rather than accumulating them.
Three design commitments shape everything:
- Full immutability. No mutation anywhere. Every value is safe to share across tasks.
- Pattern matching is the only way to branch. No
if, no earlyreturnoutside of error flow. The exhaustiveness checker makes sure every case is handled. - CSP concurrency with real parallelism. Lightweight tasks on a
thread pool, communicating through channels. I/O inside a task
transparently yields — no
async/awaitcolouring.
vs. Rust
- You don’t manage memory or lifetimes. silt uses a garbage collector.
- You don’t write type annotations. Inference is complete for idiomatic code.
- You don’t get zero-cost abstractions — silt is an interpreter, not a native compiler. If you need every cycle, silt is the wrong tool.
- You do get: Result +
?, exhaustive pattern matching, ADTs, traits, typed errors. The error-handling shape is familiar to Rust programmers.
vs. Go
- Every value is immutable. Data races are not part of the language — a task running in parallel can see a shared value without a lock.
- Errors are values of a typed enum, not interface-typed strings. You
pattern-match on specific variants (
Err(io.NotFound(path)) -> ...) and fall back to.message()for the long tail. - No
nil.Option(a)is the only way to model absence, and the type checker makes you handle theNonecase. - You still get CSP with channels and cheap tasks.
vs. Gleam
- silt has CSP built on real threads, not the BEAM. Tasks execute on an OS thread pool; I/O yields transparently.
- Imports are qualified by default (
list.map(xs, f)) rather than the flat module import style. Large programs stay readable. - No
actorsas a first-class concept — use channels.
vs. OCaml / ReScript
- Syntax leans toward C-family (
fn, braces) rather than ML-style (let … in). Familiar to most programmers on day one. - Nominal records (
type User { name: String, age: Int }) are first-class; anonymous structural records and row polymorphism are also available — see Types. Record update is a first-class operator:user.{ age: 31 }. - The standard library is larger and more task-focused.
http,json,channel,stream,tcp, andtimeship in-box by default;postgresis available as an opt-in feature (build with--features postgres).
When not to use silt
- Hot numerical loops — silt is an interpreter. If you are counting nanoseconds, use Rust or C.
- Systems programming — no
unsafe, no raw pointers, no inline assembly. silt cannot implement its own allocator. - Iterative mutation-heavy algorithms — dynamic programming and
graph algorithms threaded through
loop/foldare more verbose than their mutable counterparts. The trade-off buys concurrency safety.
Where to go next
- Getting Started — install and walk through the language in under 30 minutes
- Language Guide — complete feature reference
- Concurrency — the CSP model in depth