// Stream B1 (fibers) — the `Io` capability + the blocking-`Io` default // (step B1.2). `Io` is threaded on `Context` exactly like `Allocator`: a // `protocol #inline` at a fixed field, whose process-wide default is a // stateless `CBlockingIo` (the mirror of `CAllocator`). // // In the blocking M:1 model there is no scheduler and no suspension: // `async(worker, ..args)` runs the worker to COMPLETION synchronously, so // the returned `Future` is born `.ready` and `await` yields the stored // result immediately. This locks the B1.2 surface — `context.io.async(...)` // with a lambda worker (annotated params) + `f.await()`. // // Worker form: a lambda `(a: i64, b: i64) -> i64 => ...` whose params are // annotated. Named-fn workers need a `::` callable-param feature that does // not exist yet and are DEFERRED. #import "modules/std.sx"; main :: () -> i32 { // Single-arg lambda worker. f1 := context.io.async((n: i64) -> i64 => n * 2, 21); v1, e1 := f1.await(); if !e1 { print("double: {}\n", v1); } // → 42 // Two-arg lambda worker — exercises the `..$args` variadic forward. f2 := context.io.async((a: i64, b: i64) -> i64 => a + b, 40, 2); v2, e2 := f2.await(); if !e2 { print("sum: {}\n", v2); } // → 42 // `now_ms` is a protocol method (a deterministic-sim Io [B1.4] can // override it); the blocking Io returns a real monotonic clock, so we // only assert it is non-negative, not an exact value. t := context.io.now_ms(); if t >= 0 { print("clock ok\n"); } return 0; }