Expressive and clear syntax
Forward pipes (|>), immutable by default,
and one obvious way to do things. Data flows top-to-bottom,
the way you wrote it - not nested inside-out.
A Rust-flavoured language with real goroutines and a Swift-like memory model - run it like a script, or ship it as a single binary.
Get started → Take a Tour GitHub
Open source · Apache-2.0 · pre-1.0
Forward pipes (|>), immutable by default,
and one obvious way to do things. Data flows top-to-bottom,
the way you wrote it - not nested inside-out.
Deterministic reference counting - closely modeled on
Swift's ARC, with automatic cycle collection added - plus
arena { } regions reclaim memory as it goes out
of scope. No borrow checker, no lifetimes, no tracing collector.
go and typed channels on an M:N scheduler.
Blocking calls park the goroutine, not the thread. No
async, no await, no function
colouring.
A bytecode VM and a REPL for fast iteration; a single, dependency-free native binary via LLVM when you ship. Same language, your choice of tier.
Result / Option / ?,
exhaustive match, traits, generics, and no
null. If you know Rust, Go, or F#, you can
already read it.
A broad standard library - HTTP, JSON, crypto, SQL, compression, and more - and a clean path to drop down into safe Rust when you need it.
Hit Run on any sample - it executes right in your browser, no install. Gossamer's VM is compiled to WebAssembly.
fn double(x: i64) -> i64 { x * 2 }
fn add(a: i64, b: i64) -> i64 { a + b }
fn clamp(lo: i64, hi: i64, x: i64) -> i64 {
if x < lo { lo } else if x > hi { hi } else { x }
}
fn main() {
let n = 3 |> double |> add(10) |> clamp(0, 100)
println!("answer: {}", n)
}
use std::http::router
// A request router - the heart of a web service. Register the route
// table once (note the {id} path parameter), then match each request.
let routes = router::new()
router::add(routes, "GET", "/")
router::add(routes, "GET", "/users/{id}")
router::add(routes, "POST", "/users")
let requests = [("GET", "/"), ("GET", "/users/42"), ("POST", "/users"), ("DELETE", "/users/42")]
for (method, path) in requests {
let status = match router::lookup(routes, method, path) {
Some(_) => "200 ok",
None => "404 not found",
}
println!("{} {} -> {}", method, path, status)
}
fn fib(n: i64) -> i64 {
if n < 2 { n } else { fib(n - 1) + fib(n - 2) }
}
fn main() {
// spawn runs fib on a goroutine; join collects its result.
let h = spawn(|| fib(30))
match h.join() {
Ok(v) => println!("fib(30) on a goroutine = {}", v),
Err(e) => eprintln!("worker failed: {}", e),
}
}
enum Shape {
Circle(f64),
Rect { w: f64, h: f64 },
Triangle(f64, f64),
}
fn area(s: &Shape) -> f64 {
match s {
Shape::Circle(r) => 3.14159 * r * r,
Shape::Rect { w, h } => w * h,
Shape::Triangle(b, h) => 0.5 * b * h,
}
}
// Top-level statements - no fn main() needed
let shapes = [Shape::Circle(3.0), Shape::Rect { w: 4.0, h: 5.0 }, Shape::Triangle(6.0, 2.0)]
for s in shapes {
println!("area = {:.2}", area(&s))
}
Short, focused guides that map what you already know onto Gossamer.
Write a .gos file and run it with the
gos toolchain - no build step needed while
you iterate:
$ gos run hello.gos
hello, gossamer
$ gos build --release hello.gos # one native binary, ready to ship
Runs on Linux (x86_64, aarch64, armv7), macOS (Intel & Apple Silicon), and Windows (x86_64).