diff --git a/examples/1036-errors-failable-smoke.sx b/examples/1036-errors-failable-smoke.sx index 2a90f32..76c354e 100644 --- a/examples/1036-errors-failable-smoke.sx +++ b/examples/1036-errors-failable-smoke.sx @@ -51,6 +51,24 @@ sm_first :: (a: s32, b: s32) -> (s32, !) { return v; } +// --- Composition (ERR E5.1): failable closures, widening, generics --- + +// Closure(...) param, try-propagated (the env is carried) +sm_run :: (cb: Closure(s32) -> (s32, !SmokeErr), n: s32) -> (s32, !SmokeErr) { + return try cb(n); +} + +// bare fn-type param: a NON-failable closure literal widens into the failable +// slot (the ∅-widening adapter wraps `{value, 0}`) +sm_widen :: (cb: (s32) -> (s32, !SmokeErr), n: s32) -> s32 { + return cb(n) catch e -1; +} + +// generic ($T) value-carrying failable composition, monomorphized per call +sm_wrap :: ($T: Type, f: Closure() -> (T, !SmokeErr)) -> (T, !SmokeErr) { + return try f(); +} + main :: () { // error.X as a typed value + {} interpolation renders the tag name e0 : SmokeErr = error.BadDigit; @@ -100,5 +118,17 @@ main :: () { hv, herr := sm_acquire(true); print("acquire ok:\n"); iv, ierr := sm_acquire(false); + + // composition: inline failable closure literal through a Closure(...) param + cl := sm_run(closure((x: s32) -> (s32, !SmokeErr) { if x < 0 { raise error.BadDigit; } return x * 2; }), 6) catch e -1; + print("closure-run: {}\n", cl); // 12 + print("closure-run-err: {}\n", sm_run(closure((x: s32) -> (s32, !SmokeErr) { raise error.Empty; }), 1) catch e -9); // -9 + + // non-failable closure literal widened into the failable bare slot + print("widen: {}\n", sm_widen(closure((x: s32) -> s32 => x + 1), 9)); // 10 + + // generic failable composition (monomorphized at s32) + print("wrap: {}\n", sm_wrap(s32, closure(() -> (s32, !SmokeErr) { return 42; })) catch e 0); // 42 + print("errors ok\n"); } diff --git a/examples/expected/1036-errors-failable-smoke.stdout b/examples/expected/1036-errors-failable-smoke.stdout index 26b45c5..b185783 100644 --- a/examples/expected/1036-errors-failable-smoke.stdout +++ b/examples/expected/1036-errors-failable-smoke.stdout @@ -16,4 +16,8 @@ acquire fail: defer A acquire ok: defer A +closure-run: 12 +closure-run-err: -9 +widen: 10 +wrap: 42 errors ok