A compiled language for people who like Python
Wyn compiles to C and links a tiny runtime — no VM, no garbage collector. Memory is managed by reference counting, concurrency is spawn/await on coroutines, and a dependency is just a git URL.
struct Job { name: string ms: int fn report(self) -> string { return "${self.name} finished in ${self.ms}ms" } } fn run_job(name: string) -> int { return name.len() * 3 // stand-in for real work } fn main() { var f1 = spawn run_job("resize") var f2 = spawn run_job("transcode") var jobs = [ Job{name: "resize", ms: await f1}, Job{name: "transcode", ms: await f2}, ] for j in jobs { println(j.report()) } }
Real program, real output — compiled on an Apple M4 before publishing.
Measured on Apple M4 — method and details on the benchmarks page.
Project, tests, binary. The terminal transcripts below are unedited.
Every tab compiles as shown. The output pane is the program's actual output.
fn count_primes(lo: int, hi: int) -> int { var count = 0 for n in lo..hi { if n < 2 { continue } var prime = true var d = 2 while d * d <= n { if n % d == 0 { prime = false; break } d = d + 1 } if prime { count = count + 1 } } return count } fn main() { // four cores, zero ceremony var a = spawn count_primes(0, 1000000) var b = spawn count_primes(1000000, 2000000) var c = spawn count_primes(2000000, 3000000) var d = spawn count_primes(3000000, 4000000) var total = await a + await b + await c + await d println("primes below 4M: ${total}") }
Automatic reference counting frees memory deterministically at scope exit. No pauses, no tuning flags, no runtime to install on the target machine.
spawn f() starts a coroutine; await collects the result. Cooperative I/O under the hood, ~5μs per spawn+await round trip.
wyn add web resolves to github.com/wynlang/web. Any host works, wyn.lock pins exact commits. No registry, no account, no publish step.
wyn bind header.h generates FFI bindings from a C header — proven against SQLite, lz4, and zstd. Forty years of C libraries, available directly.
Formatter, test runner, REPL, doc generator, LSP for VS Code and Neovim. One binary installs all of it.
Linux, macOS, Windows targets from one machine — plus iOS, Android, and WebAssembly builds from the same source.
The official web package is a thin layer over Wyn's native HTTP: parse the request, respond with a helper, spawn a handler per connection. It sustains ~7,000 req/s at 200 concurrent connections with zero failed requests on an Apple M4 — with keep-alive work in flight to push that much higher.
import web fn handle(conn: int) { var req = web.read_request(conn) if req.len() == 0 { return } if web.is(req, "GET", "/") == 1 { web.html(req, 200, web.page("Hello", "<h1>Hello from Wyn</h1>", "")) } else { web.not_found(req) } } fn main() { var server = web.listen(8080) println("http://localhost:8080") while true { var conn = web.accept(server) if conn > 0 { spawn handle(conn) } } }
An honest snapshot — including the rows we lose.
| Trait | Wyn | Go | Rust | Python |
|---|---|---|---|---|
| Native binary, no runtime install | ✓ | ✓ | ✓ | ✗ |
| No garbage collector | ✓ | ✗ | ✓ | ✗ |
| Sub-second builds | ✓ | ✓ | ✗ | — |
List comprehensions, slices, in | ✓ | ✗ | ✗ | ✓ |
| Lightweight spawn/await tasks | ✓ | ✓ | ✗ | ✗ |
Generators with yield | ✓ | ✗ | ✗ | ✓ |
| Mature ecosystem | ✗ | ✓ | ✓ | ✓ |
| Production track record | early | ✓ | ✓ | ✓ |
Every Wyn install ships with a wyvern in the error messages. Install it, break something, and Wynter will point you at the line.