Comparison

Glide vs Go.
A fair head-to-head.

Both languages give you M:N coroutines, channels, and a one-binary toolchain. The Glide programming language by Murillo Deolino picks different defaults from Go in four places: memory safety (compile-time vs GC), generics + traits, errors-as-values, and the type system's expressiveness.

gc

No garbage collector

Go relies on a concurrent tracing GC — easy on the developer, but with steady CPU overhead and occasional latency spikes that matter in tight loops, low-latency systems, and small-memory targets. Glide uses scope-bound borrows and arenas: the compiler tracks ownership at compile time, freeing happens at block exit, no runtime tracing. The mental model is closer to Rust than Go, but with no lifetime annotations to write.

glide.glide
fn parse_tree() {
    let arena: *Arena = Arena::new(4096);
    defer arena.free();
    let n1: *Node = arena.create(Node);
    let n2: *Node = arena.create(Node);
}                              // arena freed in one shot
go.go
func parseTree() {
    n1 := &Node{}
    n2 := &Node{}
    _ = n1; _ = n2
}                              // GC collects whenever
!T

Errors as values, but typed

Go's error model is "return a value and an error, check if err != nil on every line". The pattern works but is verbose, and the type system doesn't enforce it — you can ignore an error and the compiler stays silent. Glide's !T is a single value, the postfix ? propagates failures in one character, and the compiler treats an unhandled !T as a hard error. Same semantics, third the boilerplate.

glide.glide
fn read_all(p: string) -> !string {
    let data: string = fs_read(p)?;
    let trimmed: string = data.trim();
    return ok(trimmed);
}
go.go
func readAll(p string) (string, error) {
    data, err := os.ReadFile(p)
    if err != nil {
        return "", err
    }
    return strings.TrimSpace(string(data)), nil
}
<T>

Real generics + traits, monomorphised

Go added generics in 1.18, but they're limited (no method-level type parameters, no associated types, no specialisation), and the implementation uses dictionary-passing for non-shape-compatible types — runtime overhead. Glide's generics are monomorphised at compile time (one C fn per concrete type) with traits, supertraits, default methods, associated types, and *dyn Trait vtable dispatch — closer to Rust than Go, with full type-level expressiveness.

glide.glide
trait Render {
    fn render(self: *Self) -> string;
}

impl Render for Box {
    fn render(self: *Box) -> string {
        return "Box";
    }
}

fn show<T: Render>(v: *T) {
    println!(v.render());
}
chan

Concurrency, the same shape you know

This is where Glide leaned hardest on Go: M:N coroutines via spawn (Go's go keyword), typed channels via chan<T>, multi-channel multiplexing via select! (Go's select), close-aware receives via while let v = c.recv(). If you're a Go programmer, the concurrency surface will feel familiar — only the syntax is slightly different.

glide.glide
fn producer(c: chan<int>) {
    for i in 0..3 { c.send(i); }
    c.close();
}

fn main() -> int {
    let c: chan<int> = make_chan(2);
    spawn producer(c);
    while let v = c.recv() { println!(v); }
    return 0;
}

When to pick which

Both deliver fast iteration loops and good concurrency. Pick by what hurts you in production.

Pick Go if…

You need the massive ecosystem (Kubernetes, Docker, every CNCF tool). You're staffing a team that has to ramp in days, not weeks. GC pauses are fine for your workload (~99% of services). You value tooling stability over language expressiveness.

Pick Glide if…

You want Go-shaped concurrency without GC pauses or runtime overhead. You need real generics and traits, not just type-parameterised funcs. You want if err != nil ergonomics without the verbosity. You're targeting smaller binaries and lower memory footprint.

Try Glide

Linux / macOS

$ curl -fsSL https://glide-lang.org/install.sh | bash

Windows (PowerShell)

> iwr https://glide-lang.org/install.ps1 -UseB | iex