A compiled language for people who like Python
v1.20 Concurrency, fast and out of the box — read the release notes → 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() { f1 = spawn run_job("resize") f2 = spawn run_job("transcode") jobs = [ Job{name: "resize", ms: await f1}, Job{name: "transcode", ms: await f2}, ] for j in jobs { print(j.report()) } }
Real program, real output - compiled on an Apple M3 Pro before publishing.
Measured on Apple M3 Pro - regenerate the req/s figure yourself with ./benchmarks/http_load.sh; 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 { count = 0 for n in lo..hi { if n < 2 { continue } prime = true 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 a = spawn count_primes(0, 1000000) b = spawn count_primes(1000000, 2000000) c = spawn count_primes(2000000, 3000000) d = spawn count_primes(3000000, 4000000) total = await a + await b + await c + await d print("primes below 4M: ${total}") }
Strings, arrays, and lambda results all chain through methods. Each snippet compiles as shown; the output line is the program's actual output.
result = "wyn, is, neat".split(",").map((s) => s.trim().upper()).join(" > ") print(result)
nums = [5, 3, 8, 1, 9, 2] top = nums.sort().reverse().slice(0, 3).sum() print(top)
words = ["compiler", "is", "an", "object", "pipeline"] caps = words.filter((s) => s.len() > 2).map((s) => s.upper()).join(" ") print(caps)
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; awaited tasks overlap cooperatively by default - no thread pool to size, no async coloring. Fire-and-forget spawn dispatches 1M tasks in ~0.7s.
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.
Opt in with [gpu] in wyn.toml and [float].map runs on Metal or OpenCL. Experimental: float32, single-op, off by default; a runtime cost model falls back to CPU, and on our M3 Pro it has not yet beaten the CPU path end-to-end, so treat it as a spike rather than a speedup. Binaries still run with no GPU.
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. The handler below loops, so the connection is reused: that sustains ~23,000 req/s with HTTP/1.1 keep-alive, and ~6,600 req/s when the client opens a fresh connection per request - zero failed requests either way, on an Apple M3 Pro. Reproduce both with ./benchmarks/http_load.sh.
import web fn handle(conn: int) { // One coroutine per CONNECTION: keep serving it // until the client hangs up (read_request -> ""). while true { 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() { server = web.listen(8080) print("http://localhost:8080") while true { 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 | ✓ | ✓ | small crates only | - |
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.