Migrating from Rust to Gossamer¶
Gossamer deliberately feels Rust-shaped: fn, struct, enum,
impl, trait, match, modules, attributes, and Result<T, E> all
look familiar. The important differences are ownership, borrowing,
concurrency, and which Rust features are intentionally absent.
Quick Map¶
| Rust | Gossamer |
|---|---|
fn f(x: i64) -> i64 { x + 1 } |
Same. |
struct Point { x: i64, y: i64 } |
Same declaration. |
Point { x: 1, y: 2 } |
Same named literal. |
tuple structs and enum variants use Name(...) |
Same. |
| named struct positional shorthand is unavailable | Point { 1, 2 } is allowed. |
Option<T> and Result<T, E> |
Same core shape. |
? |
Same propagation model. |
async fn and .await |
Use go expr plus channels or blocking calls. |
std::thread::spawn |
go fn() { ... }() |
Box<dyn Trait> |
Prefer generics or an enum. |
cargo build |
gos build |
cargo test |
gos test |
cargo fmt |
gos fmt |
Entry files may omit fn main. Bare statements at file scope become an
implicit fn main().
Ownership And References¶
Gossamer does not expose Rust's ownership-by-move model or lifetime syntax. Heap aggregates are runtime-managed, primitives copy by value, and references are ordinary aliases.
&mut still means the callee may write through the reference, but the
compiler does not implement Rust's lifetime or non-lexical-borrow analysis.
As in Rust, a writable place must be passed explicitly as &mut value;
function(value) never creates a mutable reference. An existing &mut T
reference can be forwarded directly.
It rejects a second simple named &mut to the same root while the first is in
lexical scope, overlapping temporary mutable references, and duplicate mutable
roots in one call. More complex aliases remain a correctness hazard as they
are in a language with shared mutable objects.
Traits¶
Traits are nominal and implemented explicitly:
trait Area {
fn area(&self) -> f64;
}
struct Circle { r: f64 }
impl Area for Circle {
fn area(&self) -> f64 { 3.14159 * self.r * self.r }
}
fn total<T: Area>(xs: [T]) -> f64 {
let mut out = 0.0
for x in xs {
out += x.area()
}
out
}
There is no unsafe in Gossamer source.
Derives And Value Operations¶
The supported user derives are intentionally small. Use derives for compiler-provided formatting, defaults, and ordering or equality when the type needs those generated implementations.
Do not port Rust derives mechanically. Clone, Copy, Hash,
Serialize, and Deserialize are not Rust-compatible derive surfaces in
Gossamer source. For JSON, use std::encoding::json APIs and the shapes
that module supports.
Aggregate values can be used directly in vectors and ordinary structs. HashMap and HashSet support is strongest for scalar and string keys; aggregate map keys have tier-specific limits, so prefer stable scalar keys when code must run across all tiers.
Async Code¶
Rust:
Gossamer:
use std::{errors, http}
fn fetch(url: &String) -> Result<String, errors::Error> {
let response = http::get(url, [])?
Ok(response.body)
}
For fan-out, spawn goroutines and collect through channels:
let (tx, rx) = channel()
for url in urls {
let tx = tx.clone()
go fn() {
tx.send(http::get(&url, []))
}()
}
let mut responses = []
for _ in urls {
responses.push(rx.recv().unwrap())
}
Blocking IO is acceptable. The runtime parks goroutines around blocking operations where the standard library provides integration.
Collections And Pipelines¶
Rust iterator method chains become std::iter pipelines. Gossamer's
pipe operator sends the left-hand value to the last argument.
Mutating collection helpers such as push, sort, insert, and
remove stay as methods.
Standard Library Map¶
| Rust | Gossamer |
|---|---|
std::fs::read_to_string(path) |
fs::read_to_string(path) |
std::fs::read(path) |
fs::read(path) |
std::fs::write(path, data) |
fs::write(path, data) |
std::env::args() |
env::args() |
std::env::var(name).ok() |
env::var(name) |
std::process::Command |
process::run(program, &args) |
std::process::exit(code) |
process::exit(code) |
Path::join |
path::join(base, part) |
std::sync::Mutex |
sync::Mutex |
std::time::Duration::from_millis |
time::Duration::from_millis |
reqwest::blocking::get(url) |
http::get(url, []) |
serde_json |
encoding::json |