Skip to content

Coming from Go

Side-by-side comparisons for Go developers.

Variables

go
// Go
name := "Alice"
var age int = 30
const PI = 3.14
wyn
// Wyn
name = "Alice"
var age: int = 30
const PI = 3.14

Functions

go
// Go
func add(a, b int) int {
    return a + b
}
wyn
// Wyn
fn add(a: int, b: int) -> int {
    return a + b
}

Error Handling

go
// Go
result, err := doSomething()
if err != nil {
    return err
}
wyn
// Wyn
var result = doSomething()
match result {
    Ok(v) => print("${v}")
    Err(e) => print("error: " + e)
}

Goroutines vs Spawn

go
// Go
go func() {
    result := heavyWork()
    ch <- result
}()
val := <-ch
wyn
// Wyn
var future = spawn heavyWork()
var val = await future

Channels

go
// Go
ch := make(chan int, 10)
ch <- 42
val := <-ch
wyn
// Wyn
ch = Task.channel(10)
Task.send(ch, 42)
val = Task.recv(ch)

Structs & Methods

go
// Go
type Point struct {
    X, Y int
}

func (p Point) Distance(other Point) float64 {
    dx := float64(other.X - p.X)
    dy := float64(other.Y - p.Y)
    return math.Sqrt(dx*dx + dy*dy)
}
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)
    }
}

Pattern Matching (vs switch)

go
// Go
switch n {
case 0:
    fmt.Println("zero")
case 1:
    fmt.Println("one")
default:
    fmt.Println("other")
}
wyn
// Wyn
match n {
    0 => print("zero")
    1 => print("one")
    _ => print("other")
}

Composing functions

Wyn has no pipe operator - compose with nested calls, or intermediate vars for readability, just like Go:

wyn
fn double(x: int) -> int { return x * 2 }
fn add1(x: int) -> int { return x + 1 }

result = double(add1(5))   // 12
// or, step by step:
a = add1(5)
b = double(a)              // 12

Performance Comparison

Apple M3 Pro, macOS 26, Wyn 1.21.0 --release, Go 1.26.5. Warm medians, re-measured for this release. Compile-time rows delete the output first, so both are a real build - go build skips the link when the binary is already current, which is why an older edition of this table said 96ms.

BenchmarkWynGo
fib(35)41.6ms48.2ms
sort 1M ints (call only)73ms83ms
spawn 10K (sequential await)24.5ms / 3.0MB13.9ms / 5.8MB
binary size (hello world)50KB2.4MB
compile time (hello world)356ms189ms

Full method and the rest of the tables: Benchmarks.

Key Differences

FeatureGoWyn
CompilationGo compilerC backend (TCC/gcc)
ConcurrencyGoroutinesspawn/await (OS thread pool)
MemoryGCARC (ref counting)
GenericsYes (1.18+)Yes (monomorphization)
Error handlingerror interfaceResult type + match
Package managergo modwyn pkg

See Also

MIT License - v1.21.0