Skip to content

Wyn vs Python

Wyn was designed for developers who like Python's syntax but need compiled performance. Both languages prioritize readability, but Wyn compiles to native binaries via C - no interpreter, no VM, no GIL.

Quick Facts

WynPython
Type systemStatic, inferredDynamic
ExecutionCompiled to C → native binaryInterpreted (CPython)
Memory managementARC (deterministic)Garbage collector
Hello world binary50KB~50MB (with runtime)
Startup time~6.9ms wall clock (C: ~6.9ms)~37ms
Concurrencyspawn/await (real parallelism)asyncio (GIL limits CPU parallelism)
Package managerwyn pkgpip

Performance Benchmarks

All benchmarks re-measured for Wyn 1.21.0 (the published release tarball, built with --release) on Apple M3 Pro, macOS 26, against Python 3.14.6, in one session on one machine. Process-level rows are wall-clock for the whole process, so a ~7ms process-startup floor is included in the Wyn row and ~37ms in the Python row. Sort and string rows time the operation itself, in-process, and both languages were fed byte-identical input.

BenchmarkWynPython 3.14Ratio
fib(35) recursive (whole process)41.6ms952ms23x faster
Hello world (whole process)6.9ms37.0ms5.4x faster
Sort 10K ints0.50ms1.6ms3.2x faster
Sort 1M ints73ms291ms4.0x faster
1M appends via StringBuilder5.6ms36ms (list + join)6.4x faster
1M appends via s = s + "x"11.5s9.9s1.2x slower
100K method chains (.upper().trim())9.2ms15ms1.6x faster
Hello world peak RSS1.4MB14.6MB10x smaller

The fib(35) benchmark is pure recursive computation - no stdlib tricks. Wyn compiles to C, so CPU-bound code runs at near-native speed. Python's interpreter adds overhead on every function call.

The s = s + "x" row is a genuine loss, and it is worth being clear about it. Wyn strings are immutable, so s = s + "x" allocates and copies the whole string on every iteration - the loop is O(n²). CPython is O(n²) on this shape too (s += "x" measures the same ~9.9s), so this is not an interpreter-vs-native difference; Wyn is simply a little slower per copy, and being compiled buys nothing when the algorithm is quadratic. Use StringBuilder - the row above is ~2,000x faster than naive concat - or build an array and .join() it.

Syntax Comparison

Wyn's syntax is intentionally close to Python. If you can read Python, you can read Wyn.

Variables and Functions

python
# Python
def greet(name: str) -> str:
    return f"Hello, {name}!"

names = ["Alice", "Bob", "Charlie"]
for name in names:
    print(greet(name))
wyn
// Wyn
fn greet(name: string) -> string {
    return "Hello, ${name}!"
}

names = ["Alice", "Bob", "Charlie"]
for name in names {
    print(greet(name))
}

Key differences: fn instead of def, curly braces instead of indentation, var for variable declarations, explicit types in function signatures.

Classes vs Structs

python
# Python
class Point:
    def __init__(self, x: int, y: int):
        self.x = x
        self.y = y

    def distance(self, other: "Point") -> float:
        return ((other.x - self.x)**2 + (other.y - self.y)**2)**0.5

p = Point(3, 4)
print(p.distance(Point(0, 0)))
wyn
// Wyn
struct Point {
    x: int
    y: int

    fn distance(self, other: Point) -> float {
        dx = (other.x - self.x) * (other.x - self.x)
        dy = (other.y - self.y) * (other.y - self.y)
        return Math.sqrt(dx + dy)
    }
}

p = Point{x: 3, y: 4}
print(p.distance(Point{x: 0, y: 0}).to_string())

No __init__ boilerplate. Fields are declared once. Methods live inside the struct body.

Concurrency

Python's GIL prevents true CPU parallelism with threads. Wyn's spawn/await runs on real OS threads.

python
# Python - limited by GIL for CPU work
import asyncio

async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            return await resp.text()

async def main():
    results = await asyncio.gather(
        fetch("https://api.example.com/a"),
        fetch("https://api.example.com/b"),
    )
wyn
// Wyn - true parallelism, no GIL
fn fetch(url: string) -> string {
    return Http.get(url)
}

f1 = spawn fetch("https://api.example.com/a")
f2 = spawn fetch("https://api.example.com/b")
r1 = await f1
r2 = await f2

No async/await coloring. No event loop setup. spawn runs the function on a thread pool worker, await gets the result.

Pattern Matching

Both languages have pattern matching, but Wyn's is more integrated with the type system.

python
# Python 3.10+
match command:
    case "quit":
        sys.exit(0)
    case "hello":
        print("Hi!")
    case _:
        print("Unknown")
wyn
// Wyn
match command {
    "quit" => System.exit(0)
    "hello" => print("Hi!")
    _ => print("Unknown")
}

Wyn also matches on enum variants and Result/Option types:

wyn
match safe_div(10, 0) {
    Ok(v) => print("result: ${v}")
    Err(e) => print("error: ${e}")
}

When to Choose Wyn

  • You need compiled performance without rewriting in C or Rust
  • You want tiny deployable binaries (50KB vs shipping a Python runtime)
  • You need real CPU parallelism without GIL workarounds
  • You're building CLI tools that need instant startup (~7ms vs ~42ms)
  • You want static types with type inference (catch bugs at compile time)
  • You want one binary deployment - no virtualenv, no pip install on the server

When to Choose Python

  • You need access to NumPy, pandas, scikit-learn, PyTorch - Python's ML ecosystem is unmatched
  • You're doing rapid prototyping where dynamic typing speeds up iteration
  • You need thousands of third-party libraries for every possible use case
  • You're working in a team that already knows Python
  • You need Jupyter notebooks for data exploration

Deployment Comparison

WynPython
Deploy artifactSingle 50KB–100KB binaryvirtualenv + requirements.txt + runtime
Docker image~5MB (scratch + binary)~150MB+ (python:slim + deps)
Startup time~7ms~42ms + import time
Memory (hello world)~1.4MB RSS~15MB RSS

Try Wyn

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

See Also

MIT License - v1.21.0