From a1b14f0c0fcb67999c1b4458a1165f323ee6d12b Mon Sep 17 00:00:00 2001 From: agra Date: Sat, 20 Jun 2026 21:55:52 +0300 Subject: [PATCH] fibers B1.2: lock async/await example 1805 (RED) Adds the blocking-Io async/await example with a seeded empty .exit marker. The example fails today (Io protocol + context.io + async/await not yet implemented); the next commit lands the Io interface + blocking impl + both __sx_default_context materializers + push-inherit fix to turn it green. Worker is a lambda with annotated params (the verified B1.2 idiom); named-fn workers are deferred pending a :: callable-param feature. --- .../1805-concurrency-io-blocking-async.sx | 35 +++++++++++++++++++ .../1805-concurrency-io-blocking-async.exit | 0 2 files changed, 35 insertions(+) create mode 100644 examples/1805-concurrency-io-blocking-async.sx create mode 100644 examples/expected/1805-concurrency-io-blocking-async.exit diff --git a/examples/1805-concurrency-io-blocking-async.sx b/examples/1805-concurrency-io-blocking-async.sx new file mode 100644 index 00000000..9bc722bd --- /dev/null +++ b/examples/1805-concurrency-io-blocking-async.sx @@ -0,0 +1,35 @@ +// 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; +} diff --git a/examples/expected/1805-concurrency-io-blocking-async.exit b/examples/expected/1805-concurrency-io-blocking-async.exit new file mode 100644 index 00000000..e69de29b