Quoin

/kɔɪn/ · pronounced “coin”

A small language built from blocks — and the messages they pass.

Quoin is a Smalltalk-inspired programming language running on a virtual machine written in Rust. First-class blocks, message passing all the way down, and multi-method dispatch at the core.

A taste of Quoin

"* Classes with <- , methods with -> , and blocks are { }
"* Types are optional — annotate where a contract matters
Point <- { |@x @y|
    dist -> { |^Double| ((@x * @x) + (@y * @y)).sqrt }
}

var p = Point.new:{ x = 3; y = 4 }
p.dist  "* 5

"* No control-flow keywords — if: is just a message to a boolean
(p.dist > 4).if:{ 'far'.print } else:{ 'near'.print }

"* Blocks are values — hand one to a collection
#(1 2 3 4 5).collect:{ |n| n * n }  "* #(1 4 9 16 25)

Fibers — coroutines, built in

"* A Fiber is a coroutine — it yields a value, then pauses
"* with all its state intact until you resume it.
var fib = Fiber.new:{
    var a = 0
    var b = 1
    { true }.whileDo:{ Fiber.yield:a; var t = a + b; a = b; b = t }
}

fib.resume  "* 0
fib.resume  "* 1
fib.resume  "* 1
fib.resume  "* 2

"* Wrap that same yielding block in a Generator and you get
"* a lazy, infinite sequence you can take from:
var fibs = Generator.from:{
    var a = 0
    var b = 1
    { true }.whileDo:{ ^> a; var t = a + b; a = b; b = t }
}
fibs.take:10  "* #(0 1 1 2 3 5 8 13 21 34)

Tasks — concurrency, overlapped

"* A Task is a fiber the scheduler runs concurrently. Spawn one and it
"* runs alongside you; join parks until it's done, then hands back its
"* value — re-readable, like a promise. No callbacks, no async/await.
use std:net/http

var home = Task.spawn:{ [HTTP]Client.get:'https://example.org/' }
"* ...get on with other work while it loads...
home.join.status  "* 200

"* Async.gather: runs many blocks as tasks at once and overlaps their
"* I/O — three HTTPS fetches, TLS handshakes and all, finish in about
"* the time of the slowest one. Results come back in spawn order.
var sites = #( 'https://quoinlang.dev/' 'https://docs.rs/' 'https://github.com/' )
var pages = Async.gather:(sites.collect:{ |u| { [HTTP]Client.get:u } })
pages.collect:{ |r| r.status }  "* #(200 200 200)
v0.1.0 · public preview