Wyn for LLMs — the language in one context window
Wyn is a compiled language: Python-like surface, transpiles to C, single static binary, ARC memory management (no GC), no exceptions, no null. This page is the minimal, correct reference for generating Wyn code. Every snippet compiles against the current compiler. When in doubt, prefer the forms shown here.
Rules that differ from Python / JS / Rust — read first
- Logical operators are the WORDS
and,or,not.&&,||,!are compile errors. - Functions:
fn name(a: int, b: string) -> int { ... }— notdef, notfunc. else if, neverelif.- No
null/nil/None-assignment: use Option types —T?,Some(x),None,.is_some(),.unwrap(),.unwrap_or(d). - No exceptions, no
try/catch: fallible functions returnResult<T, E>—Ok(v),Err(e), propagate with?, handle withmatch. - String interpolation is
"count: ${n}"— NOT anf"..."prefix, NOT{n}. - Assignment declares:
x = 5(mutable, inferred).const PI = 3for constants. There is nolet. - One lambda form:
(x) => expr. - Blocks use braces
{ }; whitespace is not significant. - Comments:
//only (no#, no block comments). print(x)is canonical and takes any printable value.- Call enum constructors qualified:
Shape.Circle(2)(match arms may use the bare name:Circle(r) => ...). - Integer division truncates (
1 / 2 == 0), like C/Go/Rust.
Core language
// functions (return type inferred if omitted); expression body with =>
fn add(a: int, b: int) -> int { return a + b }
fn square(n: int) -> int => n * n
fn greet(who: string = "world") -> string { return "hello, ${who}" }
// structs + methods
struct Point { x: int, y: int }
impl Point {
fn dist2(self) -> int { return self.x * self.x + self.y * self.y }
}
// enums with payloads + pattern matching (match is an expression)
enum Shape { Circle(int), Rect(int, int) }
fn area(s: Shape) -> int {
return match s {
Circle(r) => r * r * 3,
Rect(w, h) => w * h,
}
}
// Option: T? returns Some(x) / None
fn find(id: int) -> Point? {
if id == 1 { return Some(Point { x: 3, y: 4 }) }
return None
}
// Result + ? propagation
fn parse_port(s: string) -> Result<int, string> {
n = s.to_int()
if n <= 0 { return Err("bad port") }
return Ok(n)
}
fn start(cfg: string) -> Result<int, string> {
port = parse_port(cfg)? // ? returns the Err upward
return Ok(port + 1)
}
fn main() {
p = find(1)
if p.is_some() { print(p.unwrap().dist2()) } // 25
c = Shape.Circle(2)
print(area(c)) // 12
match start("8080") {
Ok(n) => print("port ${n}"),
Err(e) => print("error: ${e}"),
}
}Collections and iteration
fn main() {
xs = [3, 1, 2] // array, type inferred
ys = [x * x for x in xs if x > 1] // list comprehension
n = xs.filter((x) => x > 1).len() // lambda form: (x) => expr
print(xs[-1]) // negative indexing: 2
if 2 in xs { print("has 2") } // `in` on arrays, maps, substrings
for i, v in xs { print("${i}: ${v}") } // enumerate built in
m = {"a": 1, "b": 2} // hashmap literal
for k, v in m { print("${k}=${v}") }
s = "hello"
print(s.upper()) // HELLO
print(s.contains("ell")) // string methods: split, trim,
print("ab" * 3) // ababab; index_of, substring, ...
for c in s.chars() { print(c) } // iterate chars via .chars()
total = 0
for i in 0..5 { total = total + i } // ranges: 0..n exclusive, 0..=n incl.
}Concurrency (no async/await coloring — any fn can be spawned)
fn work(n: int) -> int { return n * 2 }
fn main() {
// spawn returns a future; await joins it
f = spawn work(21)
r = await f
print(r) // 42
// parallel block: spawn several, all joined at the block end
parallel {
a = spawn work(1)
b = spawn work(2)
}
print(a + b) // 6
// channels: channel(cap), .send(v), .recv(), .close()
ch = channel(4)
ch.send(10)
print(ch.recv()) // 10
}Caveats: parallel { } binds only statically named results (a = spawn f()), not loops. To fan out over a dynamic collection today, spawn fire-and-forget tasks that send results to a channel.
Common stdlib calls
text = File.read("in.txt") // File.read / File.write / File.exists
File.write("out.txt", text)
body = Http.get("http://api.example.com/x") // Http.get / Http.post
token = Env.get("API_TOKEN")
Http.set_header("Authorization", "Bearer ${token}")
j = Json.parse("{\"name\":\"Ada\"}") // top-level field access
name = Json.get(j, "name")
args = System.args() // CLI args; Env.get("HOME") for env
Time.sleep(100) // ms
print(Math.round(3.7)) // Math.round / abs / min / max / sqrtProject workflow
wyn run main.wyn # compile + run
wyn check main.wyn # type-check only (fast: <50ms for 10k lines); exit 1 on error
wyn build main.wyn # produce a native binary
wyn fmt main.wyn # format
wyn test # run tests (files named test_* / *_test)
wyn init myapp --template cli # new project
wyn add github.com/wynlang/args@v1 # git-URL packageThe tight loop for generated code: write file → wyn check file.wyn → read the error (errors name the fix, e.g. "'&&' has been removed - use and instead") → patch → wyn run.
Mistakes models make most, with the fix
| You wrote | Write instead |
|---|---|
a && b, a || b, !a | a and b, a or b, not a |
def f(): | fn f() { |
elif | else if |
f"n is {n}" | "n is ${n}" |
x = null / x = None | Option type: fn f() -> int? + Some(x) / None |
try { } catch { } | return Result<T, E>; use match / ? |
let x = 5 | x = 5 |
range(10) | 0..10 |
for c in "abc" | for c in "abc".chars() |
xs.map(f).sort() chained | split it: t = xs.map(f) then t.sort() |
lambda x: x + 1 / |x| x + 1 | (x) => x + 1 |
println(...) | print(...) |
String::from("hi") / Module::fn | plain "hi"; Module.fn() |
More: full docs at https://wynlang.com/docs/, machine index at https://wynlang.com/llms.txt, whole-language tour at https://wynlang.com/docs/getting-started/learn-wyn-in-y-minutes