Skip to content

Learn Wyn in Y Minutes

The whole language on one page — in the style of learnxinyminutes. Every snippet below compiles and runs against the current compiler. Copy the whole thing into tour.wyn and wyn run tour.wyn.

wyn
// ============================================================
//  Learn Wyn in Y minutes
// ============================================================

// Line comments start with //.  There are no block comments.

// ---- Functions ----
// `fn name(params) -> ReturnType { ... }`.  The return type is inferred if omitted.
fn add(a: int, b: int) -> int { return a + b }

// Expression-body functions: `-> T => expr`
fn square(n: int) -> int => n * n

// Default + named arguments
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 }
    fn shifted(self, dx: int, dy: int) -> Point {
        return Point { x: self.x + dx, y: self.y + dy }
    }
}

// ---- Enums with payloads + pattern matching ----
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,
    }
}

// ---- Optionals (T?) ----
fn find(id: int) -> Point? {
    if id == 1 { return Some(Point { x: 3, y: 4 }) }
    return None
}

// ---- Generics ----
fn identity<T>(x: T) -> T { return x }

fn main() {
    // ---- Variables ----
    var count = 10          // mutable, type inferred
    const PI = 3            // constant
    count = count + 1
    print(count)          // 11

    // ---- Strings & interpolation ----
    var name = "Wyn"
    print("Language: ${name}, len ${name.len()}")
    print("UP: ${name.upper()}  low: ${name.lower()}")

    // ---- Calling functions ----
    print(add(2, 3))          // 5
    print(square(6))          // 36
    print(greet())            // hello, world
    print(greet("friend"))    // hello, friend

    // ---- Control flow: braces OR a braceless single statement ----
    if count > 10
        print("big")
    else
        print("small")

    for i in 0..3
        print("i=${i}")

    var total = 0
    for i in 1..=5 { total = total + i }   // 1..=5 is inclusive
    print(total)                          // 15

    // ---- Collections ----
    var xs = [1, 2, 3, 4, 5]
    print(xs[0])       // 1
    print(xs[-1])      // 5   (negative index)
    print(xs[1:3])     // [2, 3]  (slice)

    var m = {"a": 1, "b": 2}
    m["c"] = 3
    for k, v in m
        print("${k} -> ${v}")

    // ---- Higher-order functions + arrow lambdas ----
    print(xs.map((n) => n * 2).filter((n) => n > 4))   // [6, 8, 10]
    print(xs.reduce((acc, n) => acc + n, 0))         // 15

    // ---- zip: parallel iteration over two collections ----
    var names = ["ada", "bob"]
    var ages  = [36, 42]
    for who, age in zip(names, ages)
        print("${who} is ${age}")

    // ---- Structs & methods ----
    var p = Point { x: 3, y: 4 }
    print(p.dist2())                 // 25
    var q = p.shifted(1, 1)
    print("${q.x},${q.y}")           // 4,5

    // ---- Enums + match ----
    print(area(Shape.Circle(2)))     // 12
    print(area(Shape.Rect(3, 5)))    // 15

    // ---- Optionals + ?. optional chaining ----
    print((find(1)?.x).unwrap_or(-1))   // 3
    print((find(2)?.x).unwrap_or(-1))   // -1  (None short-circuits)
    match find(1) {
        Some(pt) => print("found ${pt.x},${pt.y}"),
        None     => print("nothing"),
    }

    // ---- Generics ----
    print(identity(99))
    print(identity("generic"))

    // ---- Closures (and copying one) ----
    var base    = 100
    var addbase = (n) => n + base
    var alias   = addbase              // copy a closure
    print(alias(5))                  // 105

    // ---- Concurrency ----
    // spawn returns a future; await blocks for its result.
    var f = spawn square(9)
    print(await f)                   // 81

    // await_all over an array of futures.
    var futs = []
    for i in 1..4 { futs.push(spawn square(i)) }
    var results = await_all(futs)
    var acc = 0
    for _, r in results { acc = acc + r }
    print(acc)                       // 1 + 4 + 9 = 14

    // parallel { } runs bound spawns concurrently and joins at the closing brace.
    parallel {
        a = spawn square(3)
        b = spawn square(4)
    }
    print(a + b)                     // 9 + 16 = 25

    // Shared atomic counter across fire-and-forget spawns.
    var counter = Shared.new(0)
    for i in 0..10
        spawn bump(counter, i)
    Time::sleep(30)
    print(Shared.get(counter))       // 0+1+...+9 = 45
}

fn bump(c: int, n: int) -> int { Shared.add(c, n); return 0 }

Where to go next

MIT License — v1.16