Skip to content

Wyn vs Rust

Wyn and Rust both compile to native code without a garbage collector. But they make very different tradeoffs. Rust prioritizes zero-cost abstractions and memory safety guarantees. Wyn prioritizes fast compilation, simple syntax, and a batteries-included stdlib.

Quick Facts

WynRust
First release20252015
Compiles toC (then native binary)Native binary (LLVM)
Memory managementARC (automatic)Ownership + borrow checker
Hello world binary49KB~400KB
Compile time (hello)400ms~3s
Compile time (medium project)~1s30s–2min
Learning curveLow (Python-like)High (ownership, lifetimes, borrows)
Unsafe codeNot neededSometimes needed

Benchmark Comparison

All benchmarks on Apple M4, macOS 15. Wyn compiled with clang -O2, Rust with cargo build --release.

BenchmarkWynRust
fib(35) recursive33ms28ms
Sort 100K ints2ms1.5ms
Hello world binary49KB~400KB
Compile time (hello)400ms~3s
Compile time (1K LOC)~1s~15s

Rust is 15–20% faster on raw compute — it uses LLVM's optimizer, which is more aggressive than GCC/Clang on C output. But Wyn compiles 7–15x faster, which matters during development.

Syntax Comparison

Structs and Methods

rust
// Rust
struct User {
    name: String,
    age: u32,
}

impl User {
    fn is_adult(&self) -> bool {
        self.age >= 18
    }

    fn greeting(&self) -> String {
        format!("Hi, {}!", self.name)
    }
}

fn main() {
    let user = User { name: String::from("Alice"), age: 25 };
    println!("{}", user.greeting());
}
wyn
// Wyn
struct User {
    name: string
    age: int

    fn is_adult(self) -> bool {
        return self.age >= 18
    }

    fn greeting(self) -> string {
        return "Hi, ${self.name}!"
    }
}

fn main() {
    var user = User{name: "Alice", age: 25}
    println(user.greeting())
}

No impl blocks, no String::from(), no &self vs self distinction, no format! macro. Wyn strings are reference-counted — you don't think about ownership.

Error Handling

Both languages use Result types. Rust has the ? operator, Wyn uses pattern matching.

rust
// Rust
fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err("division by zero".to_string())
    } else {
        Ok(a / b)
    }
}

fn main() {
    match divide(10.0, 3.0) {
        Ok(v) => println!("result: {v}"),
        Err(e) => println!("error: {e}"),
    }
}
wyn
// Wyn
fn divide(a: int, b: int) -> Result<int, string> {
    if b == 0 { return Err("division by zero") }
    return Ok(a / b)
}

fn main() {
    match divide(10, 3) {
        Ok(v) => println("result: ${v}")
        Err(e) => println("error: ${e}")
    }
}

Similar pattern, but Wyn doesn't require .to_string(), semicolons, or turbofish syntax.

Concurrency

Rust requires Arc<Mutex<T>> or channels for shared state. Wyn uses spawn/await with automatic thread safety.

rust
// Rust
use std::thread;

fn fib(n: u64) -> u64 {
    if n <= 1 { return n; }
    fib(n - 1) + fib(n - 2)
}

fn main() {
    let handles: Vec<_> = (0..4)
        .map(|_| thread::spawn(|| fib(38)))
        .collect();

    let total: u64 = handles
        .into_iter()
        .map(|h| h.join().unwrap())
        .sum();

    println!("total: {total}");
}
wyn
// Wyn
fn fib(n: int) -> int {
    if n <= 1 { return n }
    return fib(n - 1) + fib(n - 2)
}

fn main() {
    var a = spawn fib(38)
    var b = spawn fib(38)
    var c = spawn fib(38)
    var d = spawn fib(38)
    println((await a + await b + await c + await d).to_string())
}

No Vec<_>, no .collect(), no .join().unwrap(). Wyn's spawn returns a typed future, await gets the value.

Memory Model

This is the biggest difference between the two languages.

Rust uses ownership and borrowing. Every value has exactly one owner. References must follow strict lifetime rules. The borrow checker catches data races and use-after-free at compile time — but it also rejects valid programs and has a steep learning curve.

Wyn uses Automatic Reference Counting (ARC). Values are reference-counted and freed when the count reaches zero. No ownership rules to learn, no lifetime annotations, no borrow checker fights. The tradeoff: ARC can't detect reference cycles (rare in practice), and atomic reference counting adds a small overhead (~2-5% on benchmarks).

For most applications — CLI tools, web servers, data processing — ARC is the right tradeoff. You get deterministic memory management without GC pauses and without fighting the compiler.

When to Choose Wyn

  • You want fast compile times (400ms vs 30s+) for rapid iteration
  • You want a simple memory model without ownership, lifetimes, or borrow checking
  • You want a batteries-included stdlib (HTTP, SQLite, JSON, bcrypt, GUI)
  • You're building CLI tools, web APIs, or scripts where Rust's safety guarantees are overkill
  • You want tiny binaries (49KB vs ~400KB)
  • You want to be productive in your first hour without reading a 500-page book

When to Choose Rust

  • You're building safety-critical systems where memory bugs are unacceptable
  • You need zero-cost abstractions and maximum runtime performance
  • You're writing OS kernels, embedded firmware, or browser engines
  • You need the crates.io ecosystem with 140,000+ packages
  • You want compile-time guarantees about data races and memory safety
  • You're building libraries that will be used by millions of developers

Compile Time Comparison

This matters more than most benchmarks. During development, you compile hundreds of times per day.

Project sizeWynRust
Hello world400ms~3s
500 LOC~800ms~10s
1,000 LOC~1s~15s
5,000 LOC~2s~45s

Wyn's two-stage compilation (Wyn → C → binary) is fast because the Wyn-to-C step is a single-pass transpiler, and C compilers are highly optimized for fast compilation.

Try Wyn

sh
curl -fsSL https://wynlang.com/install.sh | sh
wyn run hello.wyn

See Also

MIT License — v1.11